Java自定义注解的实现

注解是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();
		}
		
	}

}




你可能感兴趣的:(Java)