首页 > 代码库 > Java利用反射实现注解简单功能
Java利用反射实现注解简单功能
//自定义一个简单的注解
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.LOCAL_VARIABLE}) public @interface Dougest { String value() default ""; }
import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.lang.annotation.Annotation; //方法测试类 @Dougest("annotation Dougest at class ") public class TestAnnotation { @Dougest("annotation Dougest at field") String a = "2"; @Dougest int b = 10000000; public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException { TestAnnotation testAnnotation = new TestAnnotation(); testAnnotation.a = "123"; System.out.println(getObjectFieldsValue(testAnnotation));//结果 ==> {a=123, b=10000000} System.out.println(getObjectFieldValueByFieldName(testAnnotation,"a"));//结果 ==> 123 System.out.println(getFieldValueByAnnotation(Dougest.class, testAnnotation));//结果 ==> {a=123, b=10000000} Dougest d = (Dougest)TestAnnotation.class.getAnnotation(Dougest.class);//结果 ==> System.out.println(d.value());//结果 ==> annotation Dougest at class } /** * 获取指定对象指定注解下属性值 * @param annotation * @param obj * @return * @throws IllegalArgumentException * @throws IllegalAccessException */ public static Object getFieldValueByAnnotation(Class<? extends Annotation> annotation,Object obj) throws IllegalArgumentException, IllegalAccessException{ if(obj == null) throw new RuntimeException("cannot getFieldValueByAnnotation for null Object"); if(annotation == null) throw new RuntimeException("cannot getFieldValueByAnnotation for null annotation"); Map<String,Object> map = new HashMap<String,Object>(); Field[] fields = obj.getClass().getDeclaredFields(); for(Field field : fields) { field.setAccessible(true); if(field.isAnnotationPresent(annotation)) { map.put(field.getName(),field.get(obj)); } } return map; } /** * 获取对象属性值 * @param obj * @return * @throws IllegalArgumentException * @throws IllegalAccessException */ @SuppressWarnings("rawtypes") public static Map<String,Object> getObjectFieldsValue(Object obj) throws IllegalArgumentException, IllegalAccessException { if(obj == null) throw new RuntimeException("cannot getObjectFieldsValue for null Object"); Map<String,Object> map = new HashMap<String,Object>(); Class clazz = obj.getClass(); Field[] fields = clazz.getDeclaredFields(); for(Field field : fields) { field.setAccessible(true); map.put(field.getName(), field.get(obj)); } return map; } /** * 获取对象属性名获取属性值 * @param obj * @return * @throws IllegalArgumentException * @throws IllegalAccessException */ @SuppressWarnings("rawtypes") public static Object getObjectFieldValueByFieldName(Object obj,String fieldName) throws IllegalArgumentException, IllegalAccessException { if(obj == null) throw new RuntimeException("cannot getObjectFieldValueByFieldName for null Object"); if(fieldName == null || "".equals(fieldName.trim())) throw new RuntimeException("cannot getObjectFieldValueByFieldName for null fieldName"); Class clazz = obj.getClass(); Field[] fields = clazz.getDeclaredFields(); for(Field field : fields) { field.setAccessible(true); if(fieldName.equals(field.getName())) return field.get(obj); } return null; } }
什么是注解(what)
定义:
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
我的理解:
编写文档:通过代码里标识的元数据生成文档。
代码分析:通过代码里标识的元数据对代码进行分析。
编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * <p>Defaults to {@code true}. */ boolean required() default true; }
自定义注解(详情见最上面代码):
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
Annotation类型里面的参数该怎么设定:
第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号。
Java利用反射实现注解简单功能