Java反射

143 阅读2分钟

1.使用反射获取类的信息

创建实体类
public class FatherClass {
    public String mFatherName;
    public int mFatherAge;
    
    public void printFatherMsg(){}
}
public class SonClass extends FatherClass{

    private String mSonName;
    protected int mSonAge;
    public String mSonBirthday;

    public void printSonMsg(){
        System.out.println("Son Msg - name : "+ mSonName + "; age : " + mSonAge);
    }

    private void setSonName(String name){
        mSonName = name;
    }

    private void setSonAge(int age){
        mSonAge = age;
    }

    private int getSonAge(){
        return mSonAge;
    }

    private String getSonName(){
        return mSonName;
    }
}

1.1获取类的所有变量信息

private static void printFields(){
    Class mClass = SonClass.class;
    System.out.println("类的名称:" + mClass.getName());
    
    // 获取所有 public 访问权限的变量
    // 包括本类声明的和从父类继承的
    Field[] fields = mClass.getFields();
    
    // 获取所有本类声明的变量(不问访问权限)
    //Field[] fields = mClass.getDeclaredFields();
    
    // 遍历变量并输出变量信息
    for (Field field :fields) {
        // 获取访问权限并输出
        int modifiers = field.getModifiers();
        System.out.print(Modifier.toString(modifiers) + " ");
        // 输出变量的类型及变量名
        System.out.println(field.getType().getName() + " " + field.getName());
    }
}

1.2获取类的所有方法信息

private static void printMethods(){
    //1.获取并输出类的名称
    Class mClass = SonClass.class;
    System.out.println("类的名称:" + mClass.getName());
    
    //2.1 获取所有 public 访问权限的方法
    //包括自己声明和从父类继承的
    Method[] mMethods = mClass.getMethods();
    
    //2.2 获取所有本类的的方法(不问访问权限)
    //Method[] mMethods = mClass.getDeclaredMethods();
    
    //3.遍历所有方法
    for (Method method : mMethods) {
        int modifiers = method.getModifiers();
        System.out.print(Modifier.toString(modifiers) + " ");
        //获取并输出方法的返回值类型
        Class returnType = method.getReturnType();
        System.out.print(returnType.getName() + " " + method.getName() + "( ");
        //获取并输出方法的所有参数
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter:parameters) {
            System.out.print(parameter.getType().getName() + " " + parameter.getName() + ",");
        }
        //获取并输出方法抛出的异常
        Class[] exceptionTypes = method.getExceptionTypes();
        if (exceptionTypes.length == 0){
            System.out.println(" )");
        }
        else {
            for (Class c : exceptionTypes) {
                System.out.println(" ) throws " + c.getName());
            }
        }
    }
}

2.访问类的私有变量和方法

2.1访问私有方法

public class TestClass {
    private String MSG = "Original";

    private void privateMethod(String head , int tail){
        System.out.print(head + tail);
    }

    public String getMsg(){
        return MSG;
    }
}
private static void getPrivateMethod() throws Exception{
    TestClass testClass = new TestClass();
    Class mClass = testClass.getClass();
    
    //2. 获取私有方法
    //第一个参数为要获取的私有方法的名称
    //第二个为要获取方法的参数的类型,参数为 Class...,没有参数就是null
    //方法参数也可这么写 :new Class[]{String.class , int.class}
    Method privateMethod = mClass.getDeclaredMethod("privateMethod", String.class, int.class);
            
    if (privateMethod != null) {
        //获取私有方法的访问权
        //只是获取访问权,并不是修改实际权限
        privateMethod.setAccessible(true);
        
        //使用 invoke 反射调用私有方法
        //testClass 要操作的对象
        //后面两个参数传实参
        privateMethod.invoke(testClass, "Java Reflect ", 666);
    }
}