JAVA自定义注解
一. 什么是注解 :
Annotation(注解)就是JDK5.0提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。
二. Java系统内置标准注解:
注解的语法比较简单,除了@符号的使用外,他基本与Java固有语法一致,JavaSE中内置三个标准注解,定义在java.lang中:
@Override:用于修饰此方法覆盖了父类的方法;
@Deprecated:用于修饰已经过时的方法;
@SuppressWarnnings:用于通知java编译器禁止特定的编译警告。
SuppressWarnings注解的常见参数值的简单说明:
1.deprecation:使用了不赞成使用的类或方法时的警告;
2.unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型;
3.fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
4.path:在类路径、源文件路径等中有不存在的路径时的警告;
5.serial:当在可序列化的类上缺少serialVersionUID 定义时的警告;
6.finally:任何 finally 子句不能正常完成时的警告;
7.all:关于以上所有情况的警告。 当然在程序正常运行后加上即可!纯属美观代码!
三. 如何自定义注解:
@Interface关键字定义注解
定义注解格式:
public @interface注解名 {定义体}
注解参数的可支持数据类型:
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
四.元注解:
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
@Target:注解所修饰的范围
@Target(ElementType.FIELD) 属性
@Target(ElementType.METHOD) 方法
@Target(ElementType.PARAMETER) 参数
@Target(ElementType.CONSTRUCTOR) 构造器
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
@Retention:
@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
@Documented (不常用)
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Inherited:(不常用)
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
四. 默认值和value
可以使用default定义默认值
如果一个属性名取名为value,则赋值时不用指明键名
即注解器里面传的参数自动赋给value里
五. 注解解释器
方法1:
方法2:
Annotation[]getAnnotations():返回该程序元素上存在的所有注解。
方法3:
boolean isAnnotationPresent(Class annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
方法4:
Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
六. 反射+注解完成一个立方注解(及可以赋值一个数的立方给它)
1. 注解类定义
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cubic {
public int value();
}
2. 利用反射完成数的立方计算
public class CubicParser {
public static void parse(Object object){
//获取到类对象
Class extends Object> class1 = object.getClass();
//获取此类中所有的属性
Field[] fields = class1.getDeclaredFields();
//遍历这些属性
for (Field field : fields) {
field.setAccessible(true);
//判断是否为Cubic类
if(field.isAnnotationPresent(Cubic.class)){
Cubic annotation = field.getAnnotation(Cubic.class);
int value = annotation.value();
try {
field.set(object,value*value*value);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catchblock
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catchblock
e.printStackTrace();
}
}
}
}
}
3. 测试类
public class Test {
@Cubic(3)
public int num1;
@Cubic(5)
public int num2;
@Cubic(20)
public int num3;
public int num4=250;
public static void main(String[] args) {
Test test=new Test();
CubicParser.parse(test);
System.out.println(test.num1);
System.out.println(test.num2);
System.out.println(test.num3);
System.out.println(test.num4);
}
}
4. 结果 num1=9 num2=25 num3=400 num4=250