直接上代码了
例子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; } } } |
|