java自定义注解,annotation


/**
 * 方法注解
 * 
 * @author wangjie
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ValueBind {}


  1. Annotation需要声明为@interface这样
  2. @Retention 是表示需要在什么级别保存该注解信息。
    可用RetentionPolicy枚举类型主要有:
                 SOURCE: 注解将被编译器丢弃。
                 CLASS  :  注解在class文件中可能。但会被VM丢弃。
                 RUNTIME: VM将在运行时也保存注解(如果需要通过反射读取注解,则使用该值)。
  3. @Target 表示该注解可以用于什么地方。可用ElementType枚举类型主要有:
  • TYPE : 类、接口或enum声明
  •  FIELD: 域(属性)声明
  •  METHOD: 方法声明
  •  PARAMETER: 参数声明
  •  CONSTRUCTOR: 构造方法声明
  •  LOCAL_VARIABLE:局部变量声明
  •  ANNOTATION_TYPE:注释类型声明
  • PACKAGE: 包声

定义就这么简单。下面看一个列子。在类上面定义和方法上面定义通过java反射来获取值。类似于javabean。

  1. 类注解定义:
    package com.lucky.annotation;
    
    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;
    
    /**
     * 类注解
     * 
     * @author wangjie
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ClassName {
    	public String name() default "";
    }
  2. 方法注解定义:
    package com.lucky.annotation;
    
    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;
    
    /**
     * 方法注解
     * 
     * @author wangjie
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Documented
    public @interface ValueBind {
    	enum fieldType {
    		STRING, INT
    	};
    
    	public fieldType type() default fieldType.STRING;
    
    	public String value() default "";
    
    }
  3. 需要注解的类
    package com.lucky.annotation;
    
    import com.lucky.annotation.ValueBind.fieldType;
    
    @ClassName(name = "class name annotaion")
    public class Annotation {
    
    	private String name;
    	private int age;
    
    	public String getName() {
    		return name;
    	}
    
    	@ValueBind(type = fieldType.INT, value = "wangjie")
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	@ValueBind(type = fieldType.INT, value = "252")
    	public void setAge(int age) {
    		this.age = age;
    	}
    }
  4. 测试类,通过java反射来获取注解类型和根据方法注解上面的值动态的设置值。
    package com.lucky.annotation;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.text.DateFormat;
    import java.util.Date;
    
    import com.lucky.annotation.ValueBind.fieldType;
    
    public class TestAnnotation {
    	private static TestAnnotation annotation = new TestAnnotation();
    
    	private TestAnnotation() {
    	}
    
    	public static TestAnnotation getInstance() {
    		return annotation;
    	}
    
    
    	public void annotation() {
    		try {
    			Object o = Class.forName("com.lucky.annotation.Annotation")
    					.newInstance();
    			Method[] methods = o.getClass().getDeclaredMethods();
    			for (Method method : methods) {
    				// 判断此方法是否有这个注解
    				if (method.isAnnotationPresent(ValueBind.class)) {
    					ValueBind bind = method.getAnnotation(ValueBind.class);
    					String value = bind.value();
    					fieldType type = bind.type();
    					if (fieldType.INT == type) {
    						Class[] paramTypeList = method.getParameterTypes();// 方法的参数列表
    						Class paramType = paramTypeList[0];
    						if (paramType == String.class) {
    							method.invoke(o, value);
    						} else if (paramType == int.class) {
    							method.invoke(o, Integer.parseInt(value));
    						} else if (paramType == float.class) {
    							method.invoke(o, Float.parseFloat(value));
    						} else if (paramType == double.class) {
    							method.invoke(o, Double.parseDouble(value));
    						} else if (paramType == Date.class) { // 日期型需要特殊转换
    							try {
    								Date d = DateFormat.getDateInstance().parse(// 将字符串转成日期型
    										value);
    								method.invoke(o, d);
    							} catch (Exception e) {
    								e.printStackTrace();
    							}
    						} else { // 其它类型试图调用以String作为参数的构造方法。
    							try {
    								Constructor ctr = paramType
    										.getDeclaredConstructor(String.class);
    								Object obj = ctr.newInstance(value);
    								method.invoke(o, obj);
    							} catch (Exception e) {
    								e.printStackTrace();
    							}
    						}
    					}
    				}
    			}
    			Annotation ann = (Annotation) o;
    			System.out.println("className: "+o.getClass().getAnnotation(ClassName.class).name()+"  name: " + ann.getName() + "  age:"
    					+ ann.getAge());
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (InstantiationException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			e.printStackTrace();
    		} catch (InvocationTargetException e) {
    			e.printStackTrace();
    		}
    	}
    
    	public static void main(String[] args) {
    		getInstance().annotation();
    	}
    }
    运行结果:
    java自定义注解,annotation
  5. 写完回家,明天继续。


你可能感兴趣的:(annotation,Class,forName,java自定义注解)