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注解的主要内容,如果未能解决你的问题,请参考以下文章

java注解的参数没有被赋值

java注解

Android APT注解处理器 ( 配置注解依赖支持的注解类型Java 版本支持 )

Java注解教程及自定义注解

java注解是怎么实现的?

Java 注解自定义注解 ( 使用注解实现简单测试框架 )