您的位置:首页 > 财经 > 产业 > Java中的注解详讲

Java中的注解详讲

2024/11/17 21:52:30 来源:https://blog.csdn.net/weixin_53755148/article/details/141790761  浏览:    关键词:Java中的注解详讲

1 什么是注解

  • jdk5提供了一个新的应用 Annotation, 注解, 注释

  • 与之前所学的注释的区别

    • 之前的注释:是给程序员看 ,让程序员知道程序(代码)有什么用,实现了什么功能

    • 今天的注解:是给编辑器或jvm看的。在编译和运行时提供一些信息,按照信息完成后续的工作

      我们在开发中经常使用注解作为配置信息的载体。类似于xml配置文件的作用。

2 注解的分类

  1. 普通注解,在编程中经常用来作为配置的注解,包括jdk自带的注解和自定义注解

    • @Override 告诉编译,当前方法按照重写的规则检查。

    • @Deprecated 告诉编译器,当前说明的内容是过时的,不建议使用的。但可以继续使用

    • @SuppressWarnings 告诉编译,当前说明的内容相关的警告可以忽略

  2. 元注解,用来说明注解的注解 。 未来还有一个概念:元数据

    用户信息:dmy , 18 , 男, 30000

    元数据:姓名,字符串类型,最长10个字符 , 性别,年龄,工资

    元注解有4个

    • @Target 用来说明当前注解都可以作用在哪些内容上

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface SuppressWarnings {}

   2.@Retention 用来说明当前注解存活范围,有3个范围, 只能3选1

RetentionPolicy.SOURCE;  //表示在原码到字节码编译过程中有效。编译后消失
RetentionPolicy.CLASS;	//表示在类加载过程中有效,加载完消失。
RetentionPolicy.RUNTIME;//表示在jvm运行时都有效。
  • 3.@Documented 用来说明当前注解在生成api文档时,会一同出现在文档中。

  • 4.@Inherited 用来说明当前注解在类继承的过程中,可以一同被继承。

3 注解语法结构

  • 注解是一个特殊的类,使用@interface 定义注解

public @interface A{}

 使用元注解,在普通注解头上来说明注解特性。至少要使用@Retention 和 @Target

@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface A {}

 注解里只能写一种内容 (可以称为属性 也 可以称为方法)

public @interface A{String i();
}
  • 该内容类型只能是以下几种

    • String

    • 8种基本类型

    • Class

    • 其他注解类型 , 当注解作为类型时,不需要加前面的@

    • 枚举类型

    • 上述所有类型的数组类型

  • 可以使用default关键字,为注解中的属性设置默认值

 

public @interface A{String name() default "dmy"  ;String[] names() default {"dmy","zs","ls"};
}

4 注解的使用

  • 使用注解,提供配置信息

    • 根据Target元注解的指定,可以在对应的类的内容上使用注解

    • 如果注解中有属性,可以在使用注解时,类似于传参的方式为属性赋值

    • 属性赋值时,需要指定属性名和其对应的属性值

    • 如果属性是数组类型,多个属性值要使用{}包含

@A(name="zhangsan",names={"zs","ls","ww"})
class B{}

 

特殊情况说明

  • 如果注解不需要传递属性值 (没有属性,都有默认值),后面的括号可有可无

@A()
@A
class B{}

 如果注解中只有一个属性需要赋值,且这个属性名叫value。赋值时可以只写值,不写名

@interface A{String value();
}

 如果注解属性是数组类型,且传参赋值时只赋予一个值,可以省略{}

@A(name="zs",names={"dmy"})
@A(name="zs",names="dmy")
class B{}

 

使用注解,获得配置信息

  • 注解在使用时,也是类的一部分

  • 可以通过反射获得注解,进而获得注解中配置的信息

  • 反射中常用的对象(Class,Field , Method , Constructor)都提供了获得注解对象的方法

@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface A {String value() ;
}

 

public class Test3 {public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {Class<B> c = B.class;A a = c.getAnnotation(A.class);System.out.println(a.value());Field i = c.getDeclaredField("i");Annotation[] annotations = i.getAnnotations();for(Annotation annotation : annotations){Method value = annotation.getClass().getMethod("value");Object v = value.invoke(annotation);System.out.println(v);}}
}@A("dmy")
class B{@A(value="dongmingyu",i="zs")@SuppressWarnings("all")int i ;
}

补充:所有的注解,都默认继承Annotation父注解类型

5 特殊情况的注解使用

  • 注解的重复使用

    • 默认情况下,无法使用两个相同的注解,修饰同一个类信息

    • 以前解决方案是定义一个新注解,新注解中有一个数组属性,可以包含多个所需要注解

@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AS {A[] value();
}
@AS({@A("zs") ,@A("ls") , @A("ww")
})
class B{}

 

  • 现在可以在注解上使用另一个注解@Repeatable(AS.class) 指定当前注解重复出现的时候,会自动的将重复的注解组成指定的那个@AS注解

    @AS还需要正常定义

@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(AS.class)
public @interface A {}@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AS {A[] value();
}

 

@A("zs")
@A("ls")
@A("ww")
class C{}

函数式接口

  • 这是lambda表达式相关的一个概念

  • lambda表达式针对的必须是接口,而且只能有一个抽象方法。这样的接口就称为函数式接口

  • 函数式接口,可以使用@FunctionalInterface声明。 在编译就会按照函数式接口的特点进行检测

 

@FunctionalInterface
interface A{void t1();
}
  • 使用注解声明,必须是函数式接口

  • 函数式接口,不一定使用注解声明

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com