Java 反射机制 简单总结

学了很久了 简单整理一下,方便后续使用

Posted by BY Diego on February 5, 2021

获取类

  • 类名.class
  • object.getClass() 实例化的对象通过getClass()方法获取
  • Class.forName(类名全路径) 属于反射

image-20210205215609033

通过反射获取类构造方法

  • newInstance() 根据传递的参数创建类的对象
  • getConstructor() 根据参数列表获取public构造方法
  • getConstructors() 获取所有public 的构造方法
  • getDeclaredConstructor() 根据对应参数 获取构造方法,包括私有构造方法
  • getDeclaredConstructors() 获取所有构造方法

如下测试类

public class AAAA {
    AAAA(){
        System.out.println("AAAA:(public)AAAA()");
    }
  	public AAAA(String str){
        System.out.println("AAAA:(public)AAAA(String) args:" + str );
    }
    private AAAA(String str1,String str2){
        System.out.println("AAAA:(private)AAAA(String,String) args:" + str1 + "," + str2);
    }
}

获取无参方法

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance();

获取有参构造

Class Aclass =  Class.forName("AAAA");
Constructor constructor = Aclass.getConstructor(String.class);
constructor.newInstance("aaaaa");

获取私有有参构造(需要通过setAccessible(true) 来使其能够被访问)

Class Aclass =  Class.forName("AAAA");
Constructor constructor1 = Aclass.getDeclaredConstructor(String.class,String.class);
constructor1.setAccessible(true);
constructor1.newInstance("bbbbb","ccccc");

image-20210205223200908

通过反射获取方法

  • invoke() 通过参数 来调用该对象的对应方法
  • getMethod() 根据参数列表获取public 方法
  • getMethods() 获取所有 public 方法
  • getDeclaredMethod() 根据对应参数 获取方法,包括私有方法
  • getDeclaredMethods()获取所有方法
public class AAAA {
    public AAAA(String str){
        System.out.println("AAAA:(public)AAAA(String) args:" + str );
    }
    public void Method(){
        System.out.println("AAAA:(public)Method()");
    }
    private void Method1(){
        System.out.println("AAAA:(private)Method1()");
    }
    public void Method2(String str){
        System.out.println("AAAA:(public)Method2() args:" + str);
    }
    private void Method3(String str){
        System.out.println("AAAA:(private)Method2() args:" + str);
    }
}

获取public 方法并执行(无参)

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance(); // 获取实例 
Method Amethod = Aclass.getMethod("Method"); //获取方法
Amethod.invoke(AObject);

获取private 方法并执行(无参)

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance(); // 获取实例 
Method Amethod1 = Aclass.getDeclaredMethod("Method1");
Amethod1.setAccessible(true); //
Amethod1.invoke(AObject);

获取public 方法并执行(有参)

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance(); // 获取实例 
Method Amethod2 = Aclass.getMethod("Method2", String.class);
Amethod2.invoke(AObject,"ddddd");

获取private 方法并执行(有参)

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance(); // 获取实例 
Method Amethod3 = Aclass.getDeclaredMethod("Method3", String.class);
Amethod3.setAccessible(true);
Amethod3.invoke(AObject,"eeeee");

image-20210205231054549

反射获取成员

  • getField() 获取public 对应成员
  • getFields() 获取public 所有成员
  • getDeclaredField() 获取指定成员
  • getDeclaredFields() 获取所有成员
  • get() 获取对应的值
  • set() 修改对应值
public class AAAA {
    public String string1 = "diego1";
    private String string2 = "diego2";
}

获取pulbic 成员

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance();
Field field1 = AObject.getClass().getField("string1");
System.out.println(field1.get(AObject));
field1.set(AObject,"Diego1");

获取私有 成员

Class Aclass =  Class.forName("AAAA");
Object AObject = Aclass.newInstance();
Field field2 = AObject.getClass().getDeclaredField("string2");
field2.setAccessible(true);
System.out.println(field2.get(AObject));
field2.set(AObject,"Diego2"); //修改值

image-20210205234359373

内部类

通过反射获取内部类

public class BBBB {
    BBBB(){

    }
    class Test{
        public Test(){
            System.out.println("BBBB:Test:Test()");
        }
        public Test(String str){
            System.out.println("BBBB:Test:Test(String)");
        }
        public void Method(){
            System.out.println("BBBB:Test:Method()");
        }
    }
}

获取内部类

Class.forName("BBBB$Test")

获取内部类的构造函数并执行

Class Bclass = Class.forName("BBBB"); //获取BBBB类
Class clas = Class.forName("BBBB$Test"); //获取内部类
Constructor constructor = clas.getConstructor(Bclass) //获取构造函数(需要有Bclass 否则找不到)
constructor.newInstance(Bclass.newInstance()); //执行

image-20210206115631879

有参数构造与之前类似

image-20210206115752172

获取方法并执行

先获取实例化的BBBB$Test,在执行

Class Bclass = Class.forName("BBBB");
Class clas = Class.forName("BBBB$Test");
Constructor constructor = clas.getConstructor(Bclass);
Object obj = constructor.newInstance(Bclass.newInstance());

Method method = clas.getMethod("Method");
method.invoke(obj);

image-20210206122438630

私有方法 以及成员调用都类似