概念
在 Java 计算机编程语言中,注解是一种可以添加到 Java 源代码的元数据。
元数据是提供有关其他数据信息的数据。也可以理解为与数据有关的数据。
更通俗的来说就是:将数据与程序元素(类、方法、成员变量等)关联。
为什么要引入注解
在使用 Annotation(注解)之前,XML 被广泛应用于描述元数据。但 XML 在某些方面上会给维护带来麻烦。比如我为某些类声明些数据,随着类的增加,XML 维护难度也随着增加。所以 Annotation 这种与代码关联更紧密的方式诞生了。
XML 和 Annotation 各有优缺点。在定义全局的配置时像 XML 这种统一管理的方式将会更好,而在进行些方法、属性、类的声明的时候 Annotation 会更易于维护。
所以许多框架是将 XML 和 Annotation 两种方式结合使用。
注解的应用
- 编译检查
- 反射中使用 Annotation
- 帮助生成帮助文档
- 通过注解生成文件
自定义注解
定义注解
注解通过 @interface
关键字进行定义
public @interface Testable {
}
使用注解:可以写在类上,方法上,参数上……..
@Testable
public class Test {
@Testable
private int test;
@Testable
public Test(@Testable int test) {
this.test = test;
}
@Testable
public void foo() {
@Testable
int b;
}
}
注解属性
注解中还可以声明属性
public @interface Testable {
String value();
}
如果注解中只有一个熟悉可以直接命名为 value ,使用时无需再声明属性名
@Testable("Test")
public void TestClass() {
}
如果有多个值。
public @interface Person {
String name() default "qinlei";
int age();
}
可以通过 属性名声明
@Person(name = "qinlei1", age = 15)
public class Test {
}
如果有默认值得可以不声明,默认会使用默认值
@Person(age = 5)
public class Test {
}
元注解
Java 5.0 在 Java.lang.annotation 提供了四种元注解,专门用于注解其他的注解:
@Documented
一个简单的 Annotations 标记注释,表示是否将注解信息添加到 Java 文档中。
@Retention
定义注解的有效范围;有三个值可以设置
RetentionPolicy.SOURCE:在源码阶段保留,编译时就不在有任何意义,不会写入字节码文件,像@Override,@SuppressWarnings 都属于这类注解。
RetentionPolicy.CLASS:在类加载时候丢失。在字节码文件的处理中有用。注解默认使用该方式。
RetentionPolicy.RUNTIME:始终有用,在代码运行时依然有效。可以通过反射获取注解信息。
@Target
表示注解可以给什么程序元素注解。@Target 可设置的值如下,可设置多个:
- ElementType.TYPE:可用于定义类、接口、enum
- ElementType.FIELD:可用于定义全局变量
- ElementType.METHOD:可用于定义方法
- ElementType.PARAMETER:可用于定义参数
- ElementType.CONSTRUCTOR:可用于定义构造器
- ElementType.LOCAL_VARIABLE:可用于定义局部变量
- ElementType.ANNOTATION_TYPE:可用于定义注解
- ElementType.PACKAGE:用于记录java文件的package信息
@Inherited
Inherited 是可继承的意思。举个例子
定义一个带 @Inherited 的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Test {
}
@Test
class Parent {
}
class Child extends Parent {
public static void main(String[] args) {
//输出Child是否有被 @Test 注解,最后的输出为 true, 如果去掉 Test 中的 @Inherited 输出为 false
System.out.println(Child.class.isAnnotationPresent(Test.class));
}
}
上面的例子中 Child
类很明显是没有被 @Test
注解的,但由于Child
继承了 Parent
。而 Parent
的注解里含有 @Inherited
,所以 Child
也可以获取到 @Test
。
Java 常见注解
@Override
定义如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
这个大家应该熟悉,主要是用于检查我们是否覆盖了父类方法时使用,用于检测是否方法名是否写错了,写错了会编辑器会提示出来。
@Deprecated
定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
这个是将方法、构造器、成员变量等标记为过时,即不建议使用了。编辑器会有提示如下:(看 info 有删除线)
image-20180816153542908@SuppressWarnings
定义如下:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
该注解用于告诉编辑器我们忽略那些警告像下面的 new ArrayList();
有一个黄色的背景。我们只要加上 @SuppressWarnings("unchecked")
那黄色背景就被我们忽略了。
�@SafeVarargs
定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}
参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。它是在 Java 1.7 的版本中加入的。
@FunctionalInterface
定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
约束 interface 只能有一个普通方法
image-20180816155147172静态方法和默认方法除外
image-20180816155348931@Repeatable
定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Repeatable 表明可重复定义注解,例子如下:
FkTag 是我们需要使用的注解,FkTags 相当于 FkTag 的容器,关键看第三段代码。
@Repeatable(FkTags.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FkTag {
String name() default "qinlei";
int age();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FkTags {
FkTag[] value();
}
//@FkTags({@FkTag(age = 5), @FkTag(age = 6)}) 下面是这一句的简化写法
@FkTag(age = 5)
@FkTag(name = "qinlei1", age = 15)
public class FkTagTest {
}
最后附上一张图
img 微信公众号图非本人画的
参考
https://blog.csdn.net/briblue/article/details/73824058
https://en.wikipedia.org/wiki/Java_annotation
http://www.cnblogs.com/skywang12345/p/3344137.html
https://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html
http://www.importnew.com/10294.html
网友评论