什么是Java注解

  • 注解:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
  • 标准注解:@Override,@Deprecated,@SuppressWarnings
  • JDK元注解:注解其他注解的注解,四个元注解分别是
    @Target,@Retention,@Documented,@Inherited
  1. @Target说明注解修饰对象的范围。
1
2
3
4
5
6
7
ElementType.CONSTRUCTOR 描述构造器
ElementType.FIELD 描述域
ElementType.LOCAL_VARIABLE 描述局部变量
ElementType.METHOD 描述方法
ElementType.PACKAGE 描述包
ElementType.PARAMETER 描述参数
ElementType.TYPE 描述类、接口(包括注解类型)或enum声明
  1. @Retention定义注解被保留时间的长短。
1
2
3
RetentionPoicy.SOURCE 源文件保留
RetentionPoicy.CLASS class文件保留
RetentionPoicy.RUNTIME 运行时保留
  1. @Documented 这个注解修饰的Annotation类可以被javadoc工具提取成文档,他是一个标记注解,没有成员。
  2. @Inherited表示被标注过的类型是被继承的,如果一个@Inherited修饰的注解类型被用于一个class,则这个注解将被用于该class的子类,他也是个标记注解。

    如何自定义一个注解

  • 定义格式
1
public @interface 注解名 {定义体}
  • 注意:只能用public或default这两个访问权修饰;参数成员只能用基本类型(byte,short,char,int,long,float,double,boolean)和String,Enum,Class,annotations以及他们的数组;
  • 一个简单例子
1
2
3
4
5
6
7
8
9
10
11
12
13
package annotationtest;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
public enum Color {BLUE, RED, GREEN};
Color fruitColor() default Color.RED;
}
1
2
3
4
5
6
7
package annotationtest;
public class Apple {
@FruitColor(fruitColor = FruitColor.Color.RED)
public String color;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package annotationtest;
import java.lang.reflect.Field;
public class FruitInfoUtil {
public static String getFruitInfo(Class<?> tClass) {
String colorString = "";
Field[] fields = tClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(FruitColor.class)) {
FruitColor fruitColor = field.getAnnotation(FruitColor.class);
colorString = fruitColor.fruitColor().toString();
}
}
return colorString;
}
}
1
2
3
4
5
6
7
8
package annotationtest;
public class FruitMain {
public static void main(String[] args) {
System.out.println("apple color:"+FruitInfoUtil.getFruitInfo(Apple.class));
}
}

原理

从上面的例子能看出,注解起作用是java的反射机制。

  • 反射是指程序在运行时能获取自身的信息
  • 反射可以获取类中的信息,包括类的构造方法,类方法,属性等等。
1
2
3
4
5
6
// 获取类的属性
Field[] fields = tClass.getDeclaredFields();
// 获取类的构造方法
Constructor[] constructors = tClass.getConstructors();
// 获取类方法
Method[] methods = tClass.getMethods();