Java Reflection 反射基础

时间:2022-10-27 10:32:08

反射基础:

package reflection;

/**
 * Created by : Infaraway
 * DATE : 2017/3/2
 * Time : 23:06
 * Funtion : Person为父类
 */
public class Person {
    public String name;
    public Integer age;
    private String address;
    private String phoneNumber;
    private String email;

    public Person() {

    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    private void personMethod(){
        System.out.println("this is personMethod...");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setName(String name, Integer age){
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
package reflection;

/**
 * Created by : Infaraway
 * DATE : 2017/3/3
 * Time : 12:17
 * Funtion : Student子类
 */
public class Student extends Person {

    public String classes;

    private String school;
    private String grade;

    public Student() {
    }

    public Student(String name, Integer age) {
        super(name, age);
    }

    private void studentMethod(String school){
        System.out.println("this is studentMethod...");
    }
}

 

最基本的反射使用为一下的代码表示:主要获取 字段 和 方法为主;

package reflection;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by : Infaraway
 * DATE : 2017/3/2
 * Time : 23:10
 * Funtion : 反射及基本用法
 */
public class testReflect {

    String className = "reflection.Student";

    /**
     * 测试反射的基本用法
     * @throws Exception
     */
    @Test
    public void testPerson() throws Exception {
        Class clazz = Class.forName("reflection.Person");

        // 1. Class类中的getFields,getMethods,getConstructors方法
        // 分别返回提供的 public 域 方法 和构造器
        // 并且包括超类的公有成员
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

        Method [] methods = clazz.getMethods();
        for (Method method: methods) {
            System.out.println(method.getName());
        }

        Constructor [] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName());
        }


        // 2. Class类中的getDeclaredFields,getDeclaredMethods,getDeclaredConstructors方法
        // 获取所有的方法包括 private方法,且只获取当前类声明的方法 // 不包括超类的成员
        Field[] fieldsDeclared = clazz.getDeclaredFields();
        for (Field field : fieldsDeclared) {
            System.out.println(field.getName());
        }


        Method [] methodsDeclared = clazz.getDeclaredMethods();
        for (Method method: methodsDeclared) {
            System.out.println("method2---"+method.getName());
        }

        Constructor [] constructorsDeclared = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructorsDeclared) {
            System.out.println(constructor.getName());
        }


        // 3.获取指定的方法   getDeclaredMethod可以获取私有的方法
        // 获取特定方法时,需要两个东西确定调用的方法:1)方法名,2)方法的参数(重载)
        Method methodSp = clazz.getDeclaredMethod("setName",String.class);
        System.out.println(methodSp);

        //当需要使用反射式,参数类型必须是包装类  int --> Integer 等等
        Method methodSp2 = clazz.getDeclaredMethod("setName",String.class, Integer.class);
        System.out.println(methodSp2);

        //4. 执行方法
        Object object = clazz.newInstance();
        methodSp.invoke(object, "zhong");



    }
}

 

也可以通过反射获取并且调用父类的方法(包括public 和private)

 

以下只提供实现上述方法的工具类:

 

package reflection;

import java.lang.reflect.Method;

/**
 * Created by : Infaraway
 * DATE : 2017/3/3
 * Time : 12:18
 * Funtion :
 */
public class ReflectUtils {

    /**
     * 返回方法
     * @param clazz 类
     * @param methodName 方法名称
     * @param args   参数列表
     * @return 返回方法(由于使用了setAccessible方法,改使private的 method也可执行)
     */
    public static Method getMethod(Class clazz, String methodName, Object...args) {
        Method method = null;
        Class [] parametersTypes = new Class[args.length];
        //得到所有参数的class
        for (int i = 0; i < args.length; i++) {
            parametersTypes[i] = args[i].getClass();
        }
        for (;clazz != Object.class; clazz = clazz.getSuperclass()){
            try {
                method = clazz.getDeclaredMethod(methodName,parametersTypes);
                method.setAccessible(true);
                return method;
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 获取clazz中的methodName方法,该方法可能是私有方法,也可能是父类中的私有方法
     * @param clazz 类
     * @param methodName 方法名称
     * @param parametersTypes 参数类型数组
     * @return 方法的对象
     */
    public static Method getSuperMehtod(Class clazz, String methodName, Class...parametersTypes){
        Method method = null;
        for (;clazz != Object.class; clazz = clazz.getSuperclass()){
            try {
                method = clazz.getDeclaredMethod(methodName, parametersTypes);
                return method;
            }catch (Exception e){
               //method不在当前类定义,继续向上转型
            }
        }
        return null;
    }

    /**
     * 反射执行调用方法,可以使public 或者 private 可以使当前类或者 父类
     * @param obj 类对象
     * @param methodName 方法名
     * @param args  参数列表
     * @return 方法的返回值
     */
    public static Object invokeMethod(Object obj, String methodName, Object...args){
        Class [] parametersTypes = new Class[args.length];
        //得到所有参数的class
        for (int i = 0; i < args.length; i++) {
            parametersTypes[i] = args[i].getClass();
        }

        try {
            Method method = getSuperMehtod(obj.getClass(), methodName, parametersTypes);
            //设置私有方法可调用
            method.setAccessible(true);
            //执行method方法 并返回方法的返回值
            return method.invoke(obj, args);
        }catch (Exception e ){
            e.printStackTrace();
        }
        return null;
    }
}

 

本文所需完整版代码:https://git.oschina.net/infaraway/basisJava/tree/master/src/reflection