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

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: 注解

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值