Java注解

注解定义

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 其实注解本身对他们注解的代码并没有直接影响,仅仅像一个段"注释"一样。

注解的创建与简单使用

创建一个注解,如上,创建一个注解,跟我们创建一个类对比:
public @interface Test {
    String str();
    int num();
}

public class A {
    String string;
    int number;
}
  • 创建注解的关键字是@interface,创建类的关键字是class
  • 注解声明一个String类型成员变量方式:String str();,而类声明一个String类型成员变量方式:String string;
使用注解:
public @interface Test {
    String str() default "sss";//可以给这个成员指定一个默认值
    int num();
}

public class A {
    @Test(num = 0)
    String string;
    @Test(str = "",num = 1)
    int number;
}

  • 看下A类中的成员变量string和int都使用了Test注解,这个注解有两个参数,在使用时需要我们以key-value形式传入,如果注解给了default值,也可以不用传
public @interface Test {
    String value();
}

public class A {
    @Test("xxx")
    String string;
}
  • 当只有一个参数时,并且声明为value时,就比较特殊,使用时可以直接@Test("xxx")这样使用。当然一个注解也可以没有参数。
到此为止,以上自己写的注解,还没有任何作用,仅仅像注释一样标在了类中的成员变量上而已,对我们的代码程序还没有丝毫影响,如果想要影响我们的代码,还需要对这些类似注释一样的东西在恰当的时机进行"解读"。

元注解

先了解下什么是元注解:在定义注解时,注解类也能够使用其他的注解声明。作用在注解类型上的注解,我们称之为 元注解。

  • @Documented:将被此注解注释的注解包含在 javadoc 中 ,它代表着这个注解会被javadoc工具提取成文档。

  • @Inherited:表示允许子类继承父类中定义的注解

  • @Retention:表示在什么级别保存该注解信息,可选参数在RetentionPolicy枚举中,它是我们在自定义注解中比较常用的元注解。

    • @Retention(RetentionPolicy.SOURCE) 源码级别,保留在源码阶段,会被编译器忽略。看下使用场景:

      • 可给APT使用,在java文件通过javac编译生成.class文件时,javac通过注解处理器可以采集到源码中注解信息,打包到Element中,在注解处理程序(AbstractProcessor的process())中处理解析注解,(在编译期间,注解处理程序由javac调起,先执行注解处理程序,再将java文件编译成class)。其主要用于生成一些辅助类文件。注解处理器对注解的应用有很多,如Glide,EventBus3,Butterknife。

      • IDE语法检查,如使用IndDef注解的注解,可以在IDE中编辑代码时限定我们的入参类型,用于替代枚举。如以下调用addPeople时对入参类型限制为0或者1

        public static final int WOMAN = 0;
        public static final int MAN = 1;
        @IntDef(value = {MAN,WOMAN})
        @Retention(RetentionPolicy.SOURCE)
        @Target(ElementType.PARAMETER)
        public @interface People{
        }
        
        
        public void addPeople(@People int people) {
        }
        
    • RetentionPolicy.CLASS,字节码级别,注解在编译时由编译器保留<u>在class文件中</u>,但Java虚拟机会忽略(即无法在运行期反射获取注解)。如:字节码增强(插桩),在字节码中写代码(class文件有自己的数据结构,主要有无符号数和表组成)

    • RetentionPolicy.RUNTIME,运行时,标记的注解由JVM保留,因此运行时环境可以使用它,在程序运行期间,通过反射技术动态获取注解与其元素,如通过注解和反射简单粗暴的实现findViewById功能:

      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.FIELD)
      public @interface InjectView {
          int value();
      }
      public class Inject {
          public static void inject(Activity activity){
                  //获取activity的Class对象
              Class<? extends Activity> aClass = activity.getClass();
              //获取所有的成员变量
              Field[] fields = aClass.getDeclaredFields();
              for (Field field : fields) {
                      //判断是否被InjectView注解
                  boolean annotationPresent = field.isAnnotationPresent(InjectView.class);
                  if (annotationPresent) {
                      field.setAccessible(true);
                      //获取注解以及其属性值
                      InjectView annotation = field.getAnnotation(InjectView.class);
                      int value = annotation.value();
                      try {
                              //进行findViewById操作
                          View view = activity.findViewById(value);
                          //给view成员变量设置值
                          field.set(activity,view);
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
      
              }
          }
      }
      public class MainActivity extends AppCompatActivity {
          @InjectView(R.id.button)
          TextView textView;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              Inject.inject(this);
              textView.setText("通过注解和反射findViewById");
          }
      }
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355