Java注解
Posted yangfei629
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java注解相关的知识,希望对你有一定的参考价值。
1、什么叫注解
一个示例:@Override就是一个注解
public class ZhujieYf @Override public String toString() return super.toString(); public static void main(String[] args)
2、注解有什么用
一个类或方法等加了一个注解:我理解就是对其加了一个标签
加了标签后对代码的逻辑不产生影响,有啥好处
a. JVM编译使用
比如某个类使用了@Override注解,则在编译时,JVM就知道这个方法时重写了父类的方法。
如果重写的方法不符合规范(如参数类型不对),JVM编译时就会报错。
b. 第三方框架使用
注解常见与一些第三方框架,如Junit Spring等,这些框架就可以通过扫描特定的注解来实现不同的功能
如Junit中被@Test注解的方法将被junit调用。 Spring中用@Component注解的类将会自动创建Bean实例。
3、如何定义注解
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Zoo String name() default "dog";
如上 用@interface修饰的就是一个注解。
这个注解有个name属性 默认值为"dog" 通过无参的方法表示
4、元注解
元注解是用来描述注解的注解,如上使用的@Target @Retention都是元注解,此外还有@Documented,@Repeatable,@Inherited
@Target:注解的使用范围,说明这个注解可以使用在类还是方法还是成员属性上。(默认所有都支持)
取值范围:
ElementType.FIELD 可以应用于成员方法。
ElementType.LOCAL_VARIABLE 可以应用于局部变量。
ElementType.METHOD 可以应用于方法。
ElementType.PACKAGE 可以应用于包声明。
ElementType.PARAMETER 可以应用于方法的参数。
ElementType.TYPE 可以应用于类 接口 枚举 注解中。
ElementType.ANNOTATION_TYPE 可以应用于注释类型。
ElementType.CONSTRUCTOR 可以应用于构造函数。
ElementType.TYPE_PARAMETER 可以写在类型变量的声明语句中(1.8新增)
ElementType.TYPE_USE 可以写在使用类型的任何语句中(声明语句、泛型和强制转换语句中的类型)(1.8新增)
后两者不常用,扩展了注解的使用范围 不仅可以定义的地方使用注解 在声明时也可以使用注解
如:
创建类实例
new@Interned MyObject();
类型映射
myString = (@NonNull String) str;
implements 语句中
class UnmodifiableList implements@Readonly List<@Readonly T> ...
throw exception声明
void monitorTemperature() throws@Critical TemperatureException ...
参考:https://www.2cto.com/kf/201605/505767.html
@Retention : 注解生命周期
@Retention(RetentionPolicy.SOURCE) //仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 会在class字节码文件中存在,但运行时无法获得,默认
@Retention(RetentionPolicy.RUNTIME) // 运行时可以通过反射获取到
@Documented:用于javaDoc生成的文档中也包含此注解。
@Inherited:注解可被子类继承
如class A extend B ,如果B使用的注解@Yf , 则A也会继承@Af注解
@Repeatable:可重复定义
如定义两个注解 @Repeatable(Zoos.class) 说明是可以重复的 值保存在Zoos里,是一个数组
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Zoos Zoo[] value(); @Documented @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Zoos.class) @Inherited public @interface Zoo String name() default "dog"; 使用 public class ZhujieYf @Zoo(name="cat") @Zoo(name="cat") private String zooName; @Override public String toString() return super.toString(); public static void main(String[] args)
5、注解属性说明
使用注解时 属性通过key=value,key=value的形式指定
如果注解只有一个value属性 则可以使用类似@Test("value")的形式使用。
示例:
@Zoo(name="cat") @Zoo(name="cat",id=1) private String zooName;
属性的范围:
a. 8大基本数据类型(byte boolean char short int long float double) (注意不支持对应的包装类)
b. Class、enum、String、其他注解
c. 上述对应的数组类型
6、注解和反射
对于@Retention(RetentionPolicy.RUNTIME)范围的注解可用反射获取。
测试代码
public class ZhujieYf @Zoo(name="cat",id=1) private String zooName; public static void main(String[] args) throws NoSuchFieldException Class<ZhujieYf> myclass = ZhujieYf.class; Field field = myclass.getDeclaredField("zooName"); field.setAccessible(true); Zoo zoo = field.getAnnotation(Zoo.class); if(zoo != null) System.out.println("field annotation="+zoo.name());
输出:field annotation=cat
同理定义在方法 会 类上,同样方法获取,主要涉及getAnnotation和getAnnotations两个方法
getAnnotation:根据指定的注解类型获取注解
getAnnotations:获取所有注解
7、注解实际就是一个接口
我们对注解生成的注解class使用javap: javap -c -v Zoo.class可以看到
实际上注解最后就是一个接口 ,此接口继承的Annotation接口
以上是关于Java注解的主要内容,如果未能解决你的问题,请参考以下文章