Java Reflection(二):Getters and Setters、私有变量和私有方法、

    技术2022-07-11  80

    1.Getters and Setters

    使用Java反射你可以在运行期检查一个方法的信息以及在运行期调用这个方法,使用这个功能同样可以获取指定类的getters和setters,你不能直接寻找getters和setters,你需要检查一个类所有的方法来判断哪个方法是getters和setters。

    首先让我们来规定一下getters和setters的特性:

    Getter

    Getter方法的名字以get开头,没有方法参数,返回一个值。

    Setter

    Setter方法的名字以set开头,有一个方法参数。

    /** * 判断getter,setter */ @Test public void methodTest() { Class clazz = ReflectionSimple.class; Method[] methods = clazz.getMethods(); for (Method method : methods) { if (isGetter(method)) { System.out.println("getter: " + method); } if (isSetter(method)) { System.out.println("setter: " + method); } } } /** * getter方法判定 * @param method * @return */ public static boolean isGetter(Method method) { if (!method.getName().startsWith("get")) { return false; } if (method.getParameterTypes().length != 0) { return false; } if (void.class.equals(method.getReturnType())) { return false; } return true; } /** * setter判定 * @param method * @return */ public static boolean isSetter(Method method) { if (!method.getName().startsWith("set")) { return false; } if (method.getParameterTypes().length != 1) { return false; } return true; }

    2.私有变量和私有方法

    在通常的观点中从对象的外部访问私有变量以及方法是不允许的,但是Java反射机制可以做到这一点。使用这个功能并不困难,在进行单元测试时这个功能非常有效。

    2.1访问私有变量

    要想获取私有变量你可以调用Class.getDeclaredField(String name)方法或者Class.getDeclaredFields()方法。Class.getField(String name)和Class.getFields()只会返回公有的变量,无法获取私有变量。

    /** * 获取私有变量 */ @Test public void privateFieldTest() { Class clazz = ReflectionSimple.class; try { ReflectionSimple simple = new ReflectionSimple(new Date(),"I like."); Field privateField = clazz.getDeclaredField("day"); privateField.setAccessible(true); Date fieldValue = (Date) privateField.get(simple); System.out.println("fieldValue = " + fieldValue); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }

    2.2访问私有方法

    访问一个私有方法你需要调用 Class.getDeclaredMethod(String name, Class[] parameterTypes)或者Class.getDeclaredMethods() 方法。 Class.getMethod(String name, Class[] parameterTypes)和Class.getMethods()方法,只会返回公有的方法,无法获取私有方法。

    /** * 获取私有方法 */ @Test public void privateMethodTest() { ReflectionSimple simple = new ReflectionSimple(new Date(),"I like."); Class clazz = ReflectionSimple.class; try { Method method = clazz.getDeclaredMethod("getDayFeeling"); method.setAccessible(true); try { String value = (String)method.invoke(simple); System.out.println("returnValue = " +value); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } }

    3.注解

    注解是Java 5的一个新特性。注解是插入你代码中的一种注释或者说是一种元数据(meta data)。这些注解信息可以在编译期使用预编译工具进行处理(pre-compiler tools),也可以在运行期使用Java反射机制进行处理。

    package reflection.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation { public String name(); public String value(); }

    在注解定义中的两个指示@Retention(RetentionPolicy.RUNTIME)和@Target(ElementType.TYPE),说明了这个注解该如何使用。 @Retention(RetentionPolicy.RUNTIME)表示这个注解可以在运行期通过反射访问。如果你没有在注解定义的时候使用这个指示那么这个注解的信息不会保留到运行期,这样反射就无法获取它的信息。 @Target(ElementType.TYPE) 表示这个注解只能用在类型上面(比如类跟接口)。你同样可以把Type改为Field或者Method,或者你可以不用这个指示,这样的话你的注解在类,方法和变量上就都可以使用了。

    /** * 注解 */ @Test public void annotationTest() { Class aClass = TheClass.class; Annotation[] annotations = aClass.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation.annotationType()); if (annotation instanceof MyAnnotation) { MyAnnotation myAnnotation = (MyAnnotation)annotation; System.out.println("name:" + myAnnotation.name()); System.out.println("value:" + myAnnotation.value()); } } }

    备注:文章参考

    Java Reflection: Getters and Setters

    Java Reflection: 私有变量和私有方法

    Java Reflection: 注解

     

    Processed: 0.011, SQL: 9