参考
概念:java提供了一种原程序中的元素关联任何信息和任何元数据的途径和方法
JDK内置系统注解:
@Override 用于修饰此方法覆盖了父类的方法;
@Deprecated 用于修饰已经过时的方法;
@Suppvisewarnings 用于通知java编译器禁止特定的编译警告。
注解按照运行机制划分
源码注解:注解只在源码中存在,编译成.class文件就不存在了;
编译时注解:注解在源码和.class文件中都存在(例:JDK自带注解);
运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解(Autowired);
自定义注解的元注解:
@Target—作用域(constructor(构造方法声明),field(字段声明),local_variable(局部变量声明),method(方法声明),package(包声明),parameter(参数声明),type(类,接口声明))
@Retention—生命周期(source:只在源码显示,编译时会丢弃。class:编译时会记录到class中,运行时忽略。runtime:运行时存在,可以通过反射读取)
Inherited—标识注解(允许子类继承)
Documented—生成Javadoc
若成员只有一个,必须为value,这个参数赋值可以不写value=XXX
成员以无参无异常方式声明。成员类型是受限的,合法的类型包括原始类型及String,Class,Annotation, Enumeration.
上面用了注解,程序中获得注解信息的方法是反射。
Class cls = Class.forName(“”);//使用类加载器加载类
cls.isAnnotationPresent(xx.class);//判断cls这个类上是否有xx的注解,找到类上注解
xx a = (xx)cls.getAnnotation(xx.class);//取得其上的注解
下面附一个实例,是框架如何使用注解描述参数。
结构图
A.java
package javaBasic;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER ,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface A {
String value();
String name() default "bingone";
int age() default 20;
}
B.java
package javaBasic;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER ,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface B {
String value();
String name() default "bingone";
}
DataClass.java
package javaBasic;
public class DataClass {
public String name;
public int age;
public DataClass(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
RunClass.java
package javaBasic;
public class RunClass {
public static void run(@A("str") String str,@B("age")int age){
System.out.println("In run Method str:" + str + "age:" + age);
}
}
TestClass.java
package javaBasic;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
/**
* 通过注解传参数
*@author gg_gogoing
*
*/
public class TestClass {
public static void parseMethod(DataClass data,Object obj,String mthname){
//验证是否有注解
//若有则两种方法:
//1. 在编译时刻已经有了对应的表,查表即可
//2. 如下的遍历方式。
if(obj instanceof RunClass){
String str = null;
int age = 0;
Method [] methods = (Method[])obj.getClass().getMethods();
for(Method method :methods){
if(method.getName().equals(mthname)){
Annotation[][] annotations = method.getParameterAnnotations();
for(Annotation[] tt : annotations){
for(Annotation t:tt){
if(t instanceof A){
str = data.name;
}else if(t instanceof B){
age = data.age;
}
}
}
RunClass.run(str, age);
}
}
}
}
public static void main(String[] args) throws Exception, RuntimeException { // 主方法
//不直接传参数,而是将一个类中的数据传入
DataClass dc = new DataClass("gg_gogoing", 20);
parseMethod(dc, new RunClass(), "run");
}
}