1. 分类
1.1 @Target
定义:标明注解在哪里使用。
其中 ElementType 有很多类型可以供我们使用,关于它的值和说明可以看下图:
使用:
@Target(ElementType.TYPE)
public @interface MyBindView {
}
复制代码
1.2 @Rentention
定义:标识这个注解怎么保存,是保存在源码中,还是编译期,还是运行期。
其中 RetentionPolicy 有3种类型,分别如下:
我们日常经常看到大的开源框架,说是编译期注解,就是 : RetentionPolicy.CLASS
.使用方式就像上述那样使用就好了。
我们还是以一个实际的例子来看一下,我们声明三个注解,分别设置为 CLASS
,RUNTIME
,SOURCE
,然后作用于一个类中的不同方法,观察编译之后的变化:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface SourceAnnotation {
}
复制代码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ClassAnnotation {
}
复制代码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface SourceAnnotation {
}
复制代码
public class MeActivity extends AppCompatActivity {
TextView tv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_me);
tv = findViewById(R.id.tv);
}
@SourceAnnotation
public void testSourceAnnotation(){}
@ClassAnnotation
public void testClassAnnotation(){}
@RuntimeAnnotation
public void testRuntimeAnnotation(){}
}
复制代码
经过 Android Studio
编译运行一下,或者使用命令编译应该也可以,然后我们看一下 MeActivity.class
文件,这个文件在我们的 build\intermediates\javac\debug\compileDebugJavaWithJavac\classes\com.xxx(我们的包名)
目录下。
MeActivity.class
public class MeActivity extends AppCompatActivity {
TextView tv;
public MeActivity() {
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(layout.activity_me);
this.tv = (TextView)this.findViewById(id.tv);
}
public void testSourceAnnotation() {
}
@ClassAnnotation
public void testClassAnnotation() {
}
@RuntimeAnnotation
public void testRuntimeAnnotation() {
}
}
复制代码
可以看到 testSourceAnnotation
方法上已经没有了 @SourceAnnotation
注解了,.class
是编译后的结果,所以会保留 @ClassAnnotation 和 @RuntimeAnnotation
.
1.3 @Documented
定义:相对于上面两个,这个可能就用的少一些了,它是一个标记注解。在使用 javac
工具为类生成帮助文档时是否保留其注解信息。
使用如下:
@Documented
public @interface MyBindView {
}
复制代码
我们也是用一个实际例子来阐述:
创建一个注解,注解应用范围为字段上,并且使用 @Documented
注解标注,如下:
@Target(ElementType.TYPE)
@Documented
public @interface MyAnnotation {
String value() default "这是Documented注解";
}
复制代码
并且在类中使用该注解:
@MyAnnotation
public class MeActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_me);
}
}
复制代码
我们利用 Android Studio
工具生成 doc
文档,点这里:
在弹出的对话框中,勾选我们要生成文档的类(这里我只生成MeActivity.java
)以及输出路径即可。
控制台底下也可以看一些日志信息:
在输出路径中,可以看到生成的文档 html
,点击打开 index.html
:
然后如果我们去掉 @Documented
,再来看一下生成的文档:
就没有我们那个声明的注解了。
1.4 @Inherited
定义:被它修饰的注解是可以被继承的,如果有一个类使用了该注解,有子类继承了,那么子类是可以使用该注解。
给一个例子看一下就是:
1.声明一个注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
String value() default "value";
}
复制代码
2.创建一个父类Person
,子类 Woman
类,然后让父类使用注解并给 value
赋值
@MyAnnotation("人")
public class Person {
}
复制代码
public class Woman extends Person{
public String getValue(){
Class<? extends Woman> womanClazz = getClass();
MyAnnotation annotation = womanClazz.getAnnotation(MyAnnotation.class);
return annotation.value();
}
}
复制代码
public class TestAnn {
public static void main(String[] args){
Woman woman = new Woman();
System.out.println(woman.getValue());
}
}
复制代码
控制台打印:
在 woman
没有定义注解,也可以获取到父类设置的注解值。
好了,今天分享就到这了,有问题评论区见哦~?