Annotation注解屋

一、注解基本语法

(1)定义

  interface关键字前面有一个@,它告诉编译器此处声明了一个注解

  因为注解都自动继承了java.lang.annotation.Annotation接口,所以,不能在extends其他类

  注解可以用在类,方法、变量、形式参数、enum等

public  @interface  AnnoTest{  
   public String name();
}

(2)注解的属性

        也叫做成员变量,注解只有成员变量,没有方法,注解的成员变量在注解的定义中以"无参数的方法"的形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

public  @interface  AnnoTest{
   //特殊属性名
   public string  value();
    
   //看着像方法,name是属性的名字,String是返回类型
   public String attr();

   //default属性默认值
   public String  attr2() default "abc";

   //一维数组的属性
   public String[] attr3();
   
}
  • 属性类型为八种基本数据类型 (byte,short,char,int,long,float,double,boolean,String,Enum,Class,annotations)以及这些类型的一维数组
  • 如果属性没有默认值,则必须为其赋值,有默认值可以重新为其赋值
  • 标记注解:不包含成员的注解叫做标记注解
  • 单成员注解:包含一个成员的注解,成员名建议写成value,当成员名是value,给其赋值时,可以省略value=(这里必须是但成员注解)

(3)注解使用

@AnnoTest(value="value",attr1="name",attr3={"a","b"})
public  class  Test{

}

 

二、java预置注解

       java预置的注解有@Deprecated,@Override,@SuppressWarnings,@SafeVarargs,@FunctionalInterface

(1)@Deprecated   过时,编译器会警告提示,源码如下:

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

(2)@Override   子类覆写父类被@Override修饰的方法

package java.lang;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

(3)@SuppressWarnings   阻止警告,开发者忽略这种警告

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
   
    * The string {@code "unchecked"} is used to suppress unchecked warnings*
    String[] value();
}

//使用
public class ListText{

  @SuppressWarnings(value="unchecked")
  public void  add()
}

(4)SafeVarargs  参数安全类型注解,提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生unChedked这样的警告,java1.7版本加入

package java.lang;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}

(5)@FunctionalInterface   函数式接口注解,java1.8加入

        函数式接口就是一个具有一个方法的普通接口,如Runnable,函数式接口很容易转换成Lambda表达式。

package java.lang;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

     

三、元注解

       元注解是一种基本注解,可以注解到注解上的注解,能够应用到其他的注解上面。元注解有五种:

       @Documented,@Retention,@Target,@Inherited,@Repeatable

(1)@Documented

         这个注解和文档有关,将注解中的元素包含到javadoc中去。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

(2)@Retention (保留策略)  

  • RetentionPolicy.SOURCE   在源文件中有效,在编译器进行编译时它被丢弃忽视,起到提醒开发人员的作用,如:@override,APT技术
在APT技术中
// 获取所有被 @ARouter 注解的 元素集合
        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ARouter.class);
//获取注解的值
 ThorAnno annotation = element.getAnnotation(ThorAnno.class);
            String value = annotation.value();
  • RetentionPolicy.CLASS      在编译class文件有效,被虚拟机丢弃,不能加载到JVM中,如butterknife,arouter,eventbus,只要引入jar时有annotationProcessor 关键词的,一般都有这个注解  如:字节码加强
  • RetentionPolicy.RUNTIME   程序运行时有效,会被加载到JVM中    如:注解+反射
//反射通过字节码获取
Class<?> clazz = this.getClass();
ThorAnno annotation = clazz.getAnnotation(ThorAnno.class);
if(annotation !=null){
   annotation.value();
}

(3)@Target

         注解运用的地方,限定运用的场景,共8种。

  • ElementType.ANNOTATION_TYPE  对一个注解进行注解
  • ElementType.CONSTRUCTOR   对构造方法注解
  • ElementType.FIELD  对属性进行注解
  • ElementType.LOCAL_VARIBLE  对局部变量进行注解
  • ElementType.METHOD  对方法注解
  • ElementType.PACKAGE   对包进行注解
  • ElementType.PARAMETER   对一个方法内的参数进行注解
  • ElementType.Type   对一个类型进行注解,如类,接口,枚举

(4)@Inherited

        一个注解被@Inherited注解了,然后这个注解又注解了一个超类,如果这个超类的子类没有任何注解的话,那么子类就继承了超类的注解。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

(5)Repeatable

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation type</em> for the
     * repeatable annotation type.
     * @return the containing annotation type
     */
    Class<? extends Annotation> value();
}

四、Android  support  annotation

(1)Nullness注解    

        用在参数或者返回值上,编译阶段注解

  • @NonNull--- 不能为空
@Retention(SOURCE)
@Target({METHOD, PARAMETER, FIELD})
public @interface NonNull {
}
  • @Nullable---可以为空
@Retention(SOURCE)
@Target({METHOD, PARAMETER, FIELD})
public @interface Nullable {
}

(2)ResourceType 注解     一般用在参数为int的id资源

  • @StringRes    字符串id资源注解
  • @XmlRes       xml文件id资源注解
  • @ColorRes
  • @AnimRes
  • @DimenRes
  • @IdRes
  • @LayoutRes
/**
 * 得到当前界面的资源文件Id
 *
 * @return
 */
@LayoutRes
protected abstract int getContentLayoutId();

(3)Threading  注解

  •  @WorkThread  工作线程

(4)overriding Methods注解

  •  @CallSuper

 

五、注解的提取

     当注解的保留策略是RetentionPolicy.RUNTIME时,程序在运行时可以通过反射来查询注解信息

(1)类上的注解提取

通过Claas对象的isAnnotationPresent()方法判断这个类是否应用了某个注解,

public boolean   inANnotationPresent(Class<? extends ANnotation>  annotationClass)

如果被注解了,通过getAnnotation()或者getAnnotations()获取Annation对象

//获取指定类型的注解
public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
//获取所有的注解
public Annotation[] getAnnotations()

获取到Annotation对象后,获取注解的属性值。

(2)获取属性和方法上的注解

Field name = Test.class.getDeclaredField("name");
if(name!=null){
  name.setAccessible(true);
  //获取一个成员变量上的注解
  Check check = a.getAnnotation(Check.class);
  if(check!=null){
    check.value();
  }
}


Method testMethod = Test.class.getDeclaredMethod("testMethod");

            if ( testMethod != null ) {
                // 获取方法中的注解
                Annotation[] ans = testMethod.getAnnotations();
                for( int i = 0;i < ans.length;i++) {
                    System.out.println("method testMethod annotation:"+ans[i].annotationType().getSimpleName());
                }
            }

 

六、注解多态

@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BaseAnno {
    String value();
     
    int type();
}


@BaseAnno(value = "a",type = 1)
public @interface ChildA {
    String value();
}



@BaseAnno(value = "b",type = 2)
public @interface ChildB {
    String value();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值