Java注解

Java注解

参考

https://blog.csdn.net/briblue/article/details/73824058

https://www.jianshu.com/p/b560b30726d4

Overview

如何理解注解(Annotation), 下面我们先来看一看注解的专业解释

Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。

以上内容来自于: CSDN

如何理解注解

我从参考中的的博客链接中学到了这样的一句话: 不要用专业名词来解释专业名词!

即使参考链接中关于Java的注解已经非常地形象了,但是我还是想用我自己的方式来解释一下。

我们先来理解这一句: Java 注解用于为 Java 代码提供元数据

姚明,我想大家都对他比较熟悉,那么闭上眼睛想一想,我们对姚明有什么印象? ,NBA选秀状元 ,火箭队球员 ,这些修饰词可以说都是关于姚明的标签(TAG) 。姚明一直以来给我的印象是非常的好的,知道后来,有了这么一个表情包:

后来我对,姚明的印象就变成了: 表情包 ,NBA选秀状元 ...。大姚的表情包太魔性了,以至于直接就充满了我的脑海。

那么想一下不管是表情包 还是 或者NBA选秀状元 等等,都是对姚明贴上去的标签 。那么反过来理解我们的注解, 注解就是给我们的代码贴上去的标签。

作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。

下面我们继续向下理解

作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。

作为元数据,注解不直接影响你的代码执行,

不管我们给姚明贴上去了什么标签,但是姚明仍然是哪个姚明,还是球迷们眼中的大姚,那么在Java中,不管对代码添加了什么注解,这段代码还是这段代码并不会改变(如果不人为对注解进行处理的话)。如果前半句理解的话,那么后半句就不用多说了吧。

注解的作用

在Java或者Android的许多的框架中都充斥的大量的注解。我想这就不用我多说了吧。

注解的分类

按照存在期间可以分为

  • 源码期,此类注解只存在于源码中,编译成为了.class 文件后就不存在了
  • 编译期,此类注解在源码和.class文件中都存在,但是在运行期间不存在。如@Override
  • 运行期,在运行阶段还起作用,甚至会影响运行逻辑的注解。像@Autowired自动注入的这样一种注解就属于运行时注解,它会在程序运行的时候把你的成员变量自动的注入进来。

系统的注解

@Override. 用于重写父类的方法

new Thread(new Runnable() {
    @Override
    public void run() {
    }
}).start();

@Deprecated ,将方法标记为不推荐使用

 @Deprecated
 private void test() {
     System.out.println("Test");
 }

SuppressWarnings 疏略警告

如上面的test方法,已经被标记为不建议使用,这时候如果使用的话,会产生警告,但是如果这时候还要使用的话是,就可以使用此注解在忽略警告。

@SuppressWarnings("deprecation")
@Override
public void call() {
    test();
}

自定义注解

声明一个自定义注解

package annotations.annotations;

//使用@interface 声明一个注解
public @interface Test {
    
}
//使用刚刚声明的注解
@Test
private void temp() {
    
}

元注解

在学习自定义注解之前,我们还需要学习一下,元注解。

元注解就是对注解的注解.

@Retention

@Retention 是保留期的意思,该注解的作用是设置注解的保留期一共有三个参数可选.

常量 解释
RetentionPolicy.SOURCE 在编译之前会被抛弃
RetentionPolicy.CLASS 保留到编译器,在运行时会被抛弃
RetentionPolicy.RUNTIME 保留到运行期
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {

}
@Documented
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {

}

标识会生成该特性的DOC文档。

@Inherited

Inherited 标示的注解,如果一个类A被它所标识了,A的所有的子类都会继承该特性。

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {

}

@Test
class A {}
class B extends A {}
class C extends B {}

因为基类A被@Test标识而且@Test注解被@Inherited注解,那么A和B也具有该注解.

@Target

Target注解的作用是标识,指定的注解是作用与什么之上的, Target是可以多选的

@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
常量值 解释
ElementType.ANNOTATION_TYPE 作用于注解
ElementType.CONSTRUCTOR 作用于构造方法
ElementType.FIELD 作用于字段
ElementType.LOCAL_VARIABLE 作用于变量
ElementType.METHOD 作用于方法
ElementType.PACKAGE 作用于包
ElementType.PARAMETER 作用于方法参数
ElementType.TYPE 作用于类/接口/枚举
ElementType.TYPE_PARAMETER 没看懂...
ElementType.TYPE_USE 没看懂...

注解的属性

注解的属性也被称作成员变量,注解中不能有方法,注解的成员变量的定义方式如下

@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
  	//通过default方法设置属性的默认值
    String tester() default "LD";

    String desc() default "Desc";
}

通过反射获取注解的信息

注意只有Runtime存活期的注解才能被反射获取到。

 private void getAnnotation() {
     Class anClass = AnnotationClass.class;
     //获取所有的注解
     Annotation[] annotationArray = anClass.getAnnotations();
     System.out.println("Array length:" + annotationArray.length);
     for (Annotation item : annotationArray) {
         //判断注解是否是我们想要的注解
         if (item.annotationType() == Test.class) {
             Test test = (Test) item;
             System.out.printf("这个类的测试者是:%s , 他对本次测试的描述是:%s
", test.tester(), test.desc());
         }
     }
 }

总结

本章的内容到此为止,现在我们对注解也有了一定的了解,在接下来我们将会着手做一个自己的Android的小小的注解框架,用来替代繁琐的findViweById 操作。

原文地址:https://www.cnblogs.com/slyfox/p/8677370.html