什么是JAVA注解
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
天哪,这真是一个糟糕的决定,反正我认为是,原因:用专业名词来介绍专业名词。
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
基本名词和应用
注解的定义
public @interface Test1 {
}
如果你要使用一个注解,只需要调用一下即可
@Test1
public class T{
}
元注解
计算机里一般 元XX 都代表最基本最原始的东西,因此,元注解就是最基本不可分解的注解。
包含: @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。
@Retention
Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
它的取值如下:
• RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
• RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
• RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
所以,我们可以看得出,当它的值为 RUNTIME 时,则可能会影响我们代码的实际运行结果,其他两种情况是不会影响运行结果的。
@Documented
顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。
@Target
Target 是目标的意思,@Target 指定了注解运用的地方。
它的取值如下:
• ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
• ElementType.CONSTRUCTOR 可以给构造方法进行注解
• ElementType.FIELD 可以给属性进行注解
• ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
• ElementType.METHOD 可以给方法进行注解
• ElementType.PACKAGE 可以给一个包进行注解
• ElementType.PARAMETER 可以给一个方法内的参数进行注解
• ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited
CSS里也有这个名词,意味着集成上层结构的属性。只不过在JAVA里,是这样子: 假如定义了@Inherited,如果子类没有应用任何注解的话,则它会继承父类的注解。
简而言之就是,这个继承指的是注解的继承,而不是成员和成员函数。
@Repeatable(since java8)
Repeatable 是可重复的意思。即表示,注解是可重复的。
在java8之前,也可以实现重复的注解。增加这个注解是为了增加可读性。
old
public @interface Person {
String area();
}
public @interface Persons {
Person[] value();
}
public class RepeatPersonDemo {
@Persons({@Person(area="中国人"),@Person(area="美国人")})
public void do() {
}
}
new
@Repeatable(Persons.class)
public @interface Person {
String area();
}
public @interface Persons {
Person[] value();
}
public class RepeatPersonDemo {
@Person(area="中国人")
@Person(area="美国人")
public void do() {
}
}
look,just语法糖
备注:
lambda表达式和默认方法 (JEP 126)
批量数据操作(JEP 107)
类型注解(JEP 104)
注:JEP=JDK Enhancement-Proposal (JDK 增强建议 ),每个JEP即一个新特性。
注解实战
测试自带注解
package Annotations;
public interface SysInterface {
public String test();
@Deprecated
public Integer test1();
}
public class Sys implements SysInterface{
//Override 重写
@Override
public String test() {
return "你好啊";
}
@Override
public Integer test1() {
return Integer.valueOf(3);
}
//忽略过期警告 接口内指定了 @Deprecated Deprecation
@SuppressWarnings("deprecation")
public static void main(String[] args) {
Sys sys = new Sys();
System.out.println(sys.test1());
}
}
自定义注解
首先我们定义自己的注解,参数可以随便调
import java.lang.annotation.*;
@Target({ElementType.TYPE,ElementType.FIELD}) //可以在低端和类上使用
@Retention(RetentionPolicy.RUNTIME) //运行时
@Inherited
@Documented
public @interface Test1 {
String Annotation1();
int number() default 12;
}
@Test1(Annotation1 = "你好啊")
public class Self1 {
@NoMember
public int T1() {
return 1;
}
}
测试
public static void main(String[] args) {
System.out.println("Hello World!");
try {
Class c = Class.forName("Self.Self1");
boolean exists = c.isAnnotationPresent(Test1.class);
if(exists) {
Test1 test1 = (Test1)c.getAnnotation(Test1.class);
System.out.println(test1.Annotation1());
}
Method[] method = c.getMethods();
for(Method m : method) {
boolean mexists = m.isAnnotationPresent(NoMember.class);
if(mexists) {
System.out.println(m.toString()+" is Annotation by " + NoMember.class);
}
//System.out.println(mexists+m.toString());
}
System.out.println();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
运行结果
Hello World!
你好啊
public int Self.Self1.T1() is Annotation by interface Self.NoMember