注解是Java 1.5引入的,目前已经被广泛引用于各种Java框架,如Hibernate,Spring等。首先介绍三个Java内置的注解:
1. @Override,重写(覆盖)注解,当我们想要重写父类的某个方法时,可以使用该注解告诉编译器我们正在覆盖一个父类方法。这样当父类的方法发生变化是编译器会报错告知我们。
2. @Deprecated,标记已经过时(弃用)的方法,通过该注解我们可以将某一个方法申明为弃用状态。
3. @SuppressWarning,该注解告知编译器忽略某些警告。
当然框架中的注解是非常多的,不再一一介绍,下面我们来实现自定义注解,看如何定义我们自己的注解:
package com.test.ann;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 下面四个注解为Java5.0定义的四个标准元注解,是用来注解其他注解的
*/
//@Target说明了目前定义的注解可以使用的范围,取值常用的有如下几个:
//CONSTRUCTOR:用于描述构造器
//PACKAGE:用于描述包
//PARAMETER:用于描述参数
//METHOD:用于描述方法
//TYPE:用于描述类,接口(包括注解类型)或enum声明
//如果该注解不存在,说明定义的注解可以在任何程序元素上使用
@Target({ElementType.METHOD,ElementType.TYPE})
//@Retenttion定义了注解的生命周期,取值有如下三个:
//SOURCE:只在源文件中有效(即源文件中保留)
//CLASS:在class文件中有效(class文件中保留)
//RUNTIME:在运行时有效(一般都使用此参数,如果使用前两个则无法在运行时解析注解)
@Retention(RetentionPolicy.RUNTIME)
//@Inherited为标记注解,没有参数,加上此注解,说明当使用我们现在定义的注解的类被子类继承时,注解也会继承到子类
@Inherited
//@Documented,也是标记注解,说明定义的注解可以被javadoc等工具文档化
@Documented
//使用@interface关键字定义注解
public @interface Description {
/*
* 注解方法的定义(其实在注解中也可以看做成员变量)有如下的规定:
* 1.不能有参数和抛出异常
* 2.方法返回类型只能为八种基本数据类型和字符串,枚举和注解以及这些类型构成的数组
* 3.可以包含默认值,通过default实现
* 4.如果只有一个方法(成员变量),最好命名为value
*/
String value();
int count() default 1; //默认值为1
}
下面我们再实现一个使用了我们上面定义的Description注解的类:
package com.test.ann;
//在类上使用定义的Description注解
@Description(value="class annotation",count=2)
public class Person {
private String name;
private int age;
//在方法上使用定义的Description注解
@Description(value="method annotation",count=3)
public String speak() {
return "speaking...";
}
}
最后就是如何解析注解了,在实现过中使用了反射:
package com.test.ann;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
//注解解析类
public class ParseAnn {
public static void main(String[] args){
//使用类加载器加载类
try {
Class c = Class.forName("com.test.ann.Person");//加载使用了定义注解的类
//找到类上的注解
boolean isExist = c.isAnnotationPresent(Description.class);
if(isExist){
//拿到注解示例
Description d = (Description)c.getAnnotation(Description.class);
System.out.println(d.value());
}
//找到方法上的注解
Method[] ms = c.getMethods();
for(Method m : ms){
boolean isMExist = m.isAnnotationPresent(Description.class);
if(isMExist){
Description d = (Description)m.getAnnotation(Description.class);
System.out.println(d.value());
}
}
//另外一种注解方式
for(Method m:ms){
Annotation[] as = m.getAnnotations();
for(Annotation a:as){
if(a instanceof Description){
Description d = (Description)a;
System.out.println(d.value());
}
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}