Java 反射

在编译过程中,无法预知该对象,类或者可能属于那些类,只能依靠程序运行时信息来发现该对象和类的真实信息,而从程序运行过程中,实现程序运行时获取对象和类的信息,这就是反射

获取类

通过反射获取类的方法有如下:

public class Test {
    public int a;
    public int b;
    private int c;
    private int d;
    public String aa;
    private String bb;
    
    public Test(){}
    public Test(int a,int b,int c,int d){
        this.a=a;
        this.b=b;
        this.c=c;
        this.d=d;
    }
    private Test(int c,int d){
        this.c=c;
        this.d=d;
    }
    
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }
    public int getC() {
        return c;
    }
    public void setC(int c) {
        this.c = c;
    }
    public int getD() {
        return d;
    }
    public void setD(int d) {
        this.d = d;
    }
    private void A(){
        System.out.println("哈哈哈");
    }
    public void B(){
        System.out.println("fdsa");
    }
    @Override
    public String toString() {
        return "Test [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + ", aa=" + aa + ", bb=" + bb + "]";
    }
}
View Code
Class<?> class_1 = Class.forName("Test");  //方法一,使用Class类的forName(String clazzName)静态方法
Class<?> class_2 = Test.class;             //方法二,调用类的class属性获取该类的对应Class对象
Test test = new Test();                    
Class<?> testClass = test.getClass();      //方法三,调用某个对象的getClass()方法。

其中,方法一和方法二都是直接根据类来取得该类的class对象,方法三则是通过类的对象取得该类的class对象。

方法一和方法二相比之下,方法二较有优势:1,代码更安全,编译时可以;2,程序性能更好,因为无需调用方法;

获取类信息

 1. 获取类的构造方法(构造器)

//获取用public修饰指定参数的构造方法,如要获取默认构造方法,参数为Test.class
Constructor<?> constructor_1 = Test.class.getConstructor(Test.class);   //getConstructor(Class<?>...parameterTypes)
//获取所有用public修饰的构造方法
Constructor<?>[] constructor_2 = Test.class.getConstructors();          //getConstructors()    
//获取指定参数的构造方法
Constructor<?> constructor_3 = Test.class.getDeclaredConstructor();     //getDeclaredConstructor(Class<?>...parameterTypes);
//获取所有的构造方法
Constructor<?>[] constructor_4 = Test.class.getDeclaredConstructors();  //getDeclaredConstructors

 2. 获取类的属性

//获取public修饰并指定的属性名
Field feild_1 = Test.class.getField("a");          //getField(String name);
//获取public修饰的所有属性名
Field[] feild_2 = Test.class.getFields();          //getFields();
//获取指定的属性名
Field feild_3 = Test.class.getDeclaredField("c");  //getDeclaredField(String name);
//获取所有的属性名
Field[] feild_4 = Test.class.getDeclaredFields();  //getDeclaredFields();

 3. 获取类的方法

//获取public修饰并指定的方法
Method method_1 = Test.class.getMethod("getA");  //getMethod(String name,Class<?>...parameterTypes);
//获取public修饰的所有方法
Method[] method_2 = Test.class.getMethods(); //getMethods() //获取指定的方法 Method method_3 = Test.class.getDeclaredMethod("A"); //getDeclaredMethod(String name,Class<?>...parameterTypes); //获取所有的方法
Method[] method_4 = Test.class.getDeclaredMethods(); //getDeclaredMethods()

使用反射生成并操作对象

1. 创建对象

//创建默认构造方法的对象(无默认构造方法则报错)
Object test_1 = Test.class.newInstance();
//创建指定构造方法的对象(可以是默认构造方法)
Constructor<?> constructor = Test.class.getDeclaredConstructor(int.class,int.class,int.class,int.class); Object test_2 = constructor.newInstance(1,3,4,5);

2. 调用方法

Object obj = method_1.invoke(test_1);   //method.invoke(Object obj,Object...parameterTypes) 第一个参数为对应类的对象,第二个参数为该方法的参数

3. 访问属性值

Test test = new Test();                                //获取对象
Field fieldI = Test.class.getDeclaredField("c");       //获取私有属性c
Field fieldII = Test.class.getField("aa");             //获取属性aa
Field fieldIII = Test.class.getDeclaredField("bb");    //获取私有属性bb
fieldI.setAccessible(true);                            //解除访问限制

 fieldI.setInt(test,1);              //八大基本数据类型设置属性 方法一 setXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写
 Object obj_1 = fieldI.getInt(test); //八大基本数据类型获取属性 方法一 getXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写
 System.out.println(obj_1);
 fieldI.set(test,12);                //八大基本数据类型设置属性 方法二 set(Object obj,Obj val)
 Object obj_2 = fieldI.get(test);    //八大基本数据类型获取属性 方法二 get(Object obj)
 System.out.println(obj_2);
 fieldII.set(test,"Test");           //复合数据类型设置属性 set(Object obj,Obj val)
 Object obj_3 = fieldII.get(test);   //复合数据类型获取属性 get(Object obj)
 System.out.println(obj_3);
 System.out.println(test);
 fieldIII.set(test,"哈哈");
 System.out.println(test);

 

 全部代码:

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

public class TestMain {
    public static void main(String[] args){
        
        try {
            Class<?> class_1 = Class.forName("Test");  //方法一
            Class<?> class_2 = Test.class;             //方法二
//            Test test = new Test();                    
//            Class<?> class_3 = test.getClass();      //方法三
            
            System.out.println("--------类----------");
            System.out.println("1"+class_1);
            System.out.println("2"+class_2);
//            System.out.println("3"+class_3);
            
            Constructor<?> constructor_1 = Test.class.getConstructor();
            Constructor<?>[] constructor_2 = Test.class.getConstructors();
            Constructor<?> constructor_3 = Test.class.getDeclaredConstructor();
            Constructor<?>[] constructor_4 = Test.class.getDeclaredConstructors();
            
            System.out.println("--------构造方法----------");
            System.out.println(constructor_1);
            System.out.println(constructor_2);
            System.out.println(constructor_3);
            System.out.println(constructor_4);
            
            //获取public修饰并指定的属性名
            Field feild_1 = Test.class.getField("a");          //getField(String name);
            //获取public修饰的所有属性名
            Field[] feild_2 = Test.class.getFields();          //getFields();
            //获取指定的属性名
            Field feild_3 = Test.class.getDeclaredField("c");  //getDeclaredField(String name);
            //获取所有的属性名
            Field[] feild_4 = Test.class.getDeclaredFields();  //getDeclaredFields();
            
            System.out.println("--------类的属性----------");
            System.out.println(feild_1);
            System.out.println(feild_2);
            System.out.println(feild_3);
            System.out.println(feild_4);
            
            //获取public修饰并指定的方法
            Method method_1 = Test.class.getMethod("getA");  //getMethod(String name,Class<?>...parameterTypes);
            //获取public修饰的所有方法
            Method[] method_2 = Test.class.getMethods();     //getMethods()
            //获取指定的方法
            Method method_3 = Test.class.getDeclaredMethod("A");  //getDeclaredMethod(String name,Class<?>...parameterTypes);
            //获取所有的方法
            Method[] method_4 = Test.class.getDeclaredMethods();  //getDeclaredMethods()
            
            System.out.println("--------类的方法----------");
            System.out.println(method_1);
            System.out.println(method_2);
            System.out.println(method_3);
            System.out.println(method_4);
            
            //创建默认构造方法的对象(无默认构造方法则报错)
            Object test_1 = Test.class.newInstance();
            //创建指定构造方法的对象(可以是默认构造方法)
            Constructor<?> constructor = Test.class.getDeclaredConstructor(int.class,int.class,int.class,int.class);
            Object test_2 = constructor.newInstance(1,3,4,5);
            System.out.println("--------创建对象----------");
            System.out.println(test_1);
            System.out.println(test_2);
            
            Object obj = method_1.invoke(test_1);
            System.out.println("--------方法调用----------");
            System.out.println(obj);
            
            Test test = new Test();
            Field fieldI = Test.class.getDeclaredField("c");
            Field fieldII = Test.class.getField("aa");
            Field fieldIII = Test.class.getDeclaredField("bb");
            fieldI.setAccessible(true);
            
            System.out.println("--------属性访问----------");
            fieldI.setInt(test,1);               //八大基本数据类型设置属性 方法一 setXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写      
            Object obj_1 = fieldI.getInt(test);  //八大基本数据类型获取属性 方法一 getXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写
            System.out.println(obj_1);
            fieldI.set(test,12);                 //八大基本数据类型设置属性 方法二 set(Object obj,Obj val)
            Object obj_2 = fieldI.get(test);     //八大基本数据类型获取属性 方法二 get(Object obj)
            System.out.println(obj_2);
            fieldII.set(test,"Test");            //复合数据类型设置属性 set(Object obj,Obj val)
            Object obj_3 = fieldII.get(test);    //复合数据类型获取属性 get(Object obj)
            System.out.println(obj_3);
            System.out.println(test);            
            fieldIII.set(test,"哈哈");
            System.out.println(test);
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
View Code
原文地址:https://www.cnblogs.com/hjlin/p/11365292.html