分享

java中反射及注解的简单使用

 dtl乐学馆 2015-02-28
直接上代码了

例子1:
@Request(value="dtl", parameter = "123")   //自定义注解的使用
public class DtlTest {
 String name;
 int age;
 String address;
 
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
  System.out.println("age is: "+age);
 }
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }
 
 public String toString(){
  String str = "this is toString method";
  return str;
 }
 
 public static void main(String[] args) {
  Class<?> t1 = null;
  Class<?> t2 = null;
  Class<?> t3 = null;
  try {
   //以下都可以
   t1 = Class.forName("DtlTest");//完整包名
   t2 = new DtlTest().getClass();
   t3 = DtlTest.class;
   DtlTest t4 = new DtlTest();
   Method[] method = t3.getDeclaredMethods();//获取所有方法
   Method method1 = t3.getMethod("toString");//获取指定方法
   //invoke方法参数,第一个就是你要调用的方法所在的类实例,第二个是入参Object数组
   System.out.println("method1:"+method1.invoke(DtlTest.class.newInstance()));
   System.out.println("method1:"+method1.invoke(t4));//这里可以直接使用类的实例
   for (int i = 0; i < method.length; i++) {
    if("toString".equals(method[i].getName())){
     String str = (String) method[i].invoke(DtlTest.class.newInstance());
     System.out.println(str);
    }
    if("setAge".equals(method[i].getName())){
     method[i].invoke(DtlTest.class.newInstance(),new Object[]{33});
    }
   }
   //解析注解,获取注解成员值
   if(t3.isAnnotationPresent(Request.class)){//判断类上是否有指定注解
    Request request = t3.getAnnotation(Request.class);
    //至此可以获取注解的成员等一切信息了
    System.out.println("request.value()=="+request.value());
    System.out.println("request.parameter()=="+request.parameter());
   }

  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InstantiationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

 
//以下是自定义的注解

/**
 如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=),
如@Description("使用注解的实例")。注解类拥有多个成员时,
如果仅对value成员进行赋值则也可不使用赋值号,如果同时对多个成员进行赋值,则必须使用赋值号,
如@DeclareParents (value = "NaiveWaiter", defaultImpl = SmartSeller.class)。
*/
/**
ANNOTATION_TYPE
          注释类型声明
CONSTRUCTOR
          构造方法声明
FIELD
          字段声明(包括枚举常量)
LOCAL_VARIABLE
          局部变量声明
METHOD
          方法声明
PACKAGE
          包声明
PARAMETER
          参数声明
TYPE
          类、接口(包括注释类型)或枚举声明
 */
/**
枚举常量摘要
CLASS
          编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME
          编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE
          编译器要丢弃的注释。
 */
//指定注解的类型、保留范围
@Target(ElementType.TYPE)    //指定注释用在什么地方
@Retention(RetentionPolicy.RUNTIME) //指定注释保留级别,只有此级别才可以使用反射获取
public @interface Request {
 String value() default "CLASS_NAME";//可以使用default设置默认值
 String parameter();
}

例子2
//通过反射实现bean的属性值的拷贝
private static void copyProperties(Object obj, Object dest, Class soureClass, Class destClass) {
  Method[] sourceMethods = soureClass.getMethods();
  Method[] destMethods = destClass.getMethods();
  for (Method getMethod : sourceMethods) {
   try {
    if (getMethod.getName().startsWith(GET)) {//拿到get方法
     for (Method setMethod : destMethods) {
      // 方法名及参数类型类型都一致才复制值
      if (setMethod.getName().startsWith(SET)
        && getMethod.getName().replaceFirst(GET, EMPTY)
          .equals(setMethod.getName().replaceFirst(SET, EMPTY))
        && getMethod.getReturnType().equals(setMethod.getParameterTypes()[0])) {
       setMethod.setAccessible(true);//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。也就是访问权限修饰符private等失去作用。
       getMethod.setAccessible(true);
       //反射调用目标类的set方法,参数是源通过get方法获取的值
       setMethod.invoke(dest, getMethod.invoke(obj));
      }
     }
    }
   } catch (Exception e) {
    logger.error(e.toString());
    continue;
   }
  }
 }
 
 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多