java中的反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

比如类Product如下:

package p0123;
public class Product {
    private String id; //编号
    private String name;//名称
    private double price;//价格
    Product(){};//无参构造方法
    Product(String id,String name,double price){//有参构造方法
        super();
        this.id  = id;
        this.name = name;
        this.price = price;
    }
    /*get和set方法*/
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
}

1、// 获得这个类的Class对象

public class ReflectTest {
    // 获得一个类Class对象
    @Test
    public void method_1() throws ClassNotFoundException{
        // 方式一 类名.class 属性获得
        Class class1 = Product.class;
        
        // 方式二 不知道类名,对象.getClass 方法
        Object object = new Product();
        Class class2 = object.getClass();
        
        // 方式三:不知道类名、也不知道对象 ,只知道类全路径描述 包名.类名
        String classPath = "p0123.Product";
        Class class3 = Class.forName(classPath);
        
        System.out.println(class1);//class p0123.Product
        System.out.println(class2);//class p0123.Product
        System.out.println(class3);//class p0123.Product
    }

}

2、创建这个类的对象,通过默认构造函数)

// 创建一个类的对象(通过默认构造函数)
    @Test
    public void method_2() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
        // 传统
        Product product = new Product();
        
        // 反射构造对象,调用默认构造函数 构造类对象
        String classPath = "p0123.Product";
        Class class1 = Class.forName(classPath);
        Object product2 = class1.newInstance();
    }

3、创建这个类的对象,通过有参构造函数

// 创建一个类对象(通过有参构造函数)
    @Test
    public void method_3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        // 传统
        Product product = new Product("1", "wang", 10);
        
        // 反射构造
        String classPath = "p0123.Product";
        Class class1 = Class.forName(classPath);
        // 如果调用有参数构造器,必须获得构造器对应Constructor对象
        // 因为构造器参数列表唯一的,通过参数类型列表 获得指定构造器
        Constructor constructor = class1.getConstructor(String.class,String.class,double.class);
        // 构造时,传入参数个数应该和获得构造器时 参数类型个数 匹配
        Object product2 = constructor.newInstance("2","zhang",20);
    }

4、读写成员变量

@Test
    public void method_4() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException{
        // 传统
        Product product = new Product();
        //product.name = "li"; name是私有的不能操作
        
        // 反射
        String classPath = "p0123.Product";
        Class class1  = Class.forName(classPath);
        Object product2 = class1.newInstance();
        
        // 用反射操作成员变量,获得变量对应Field对象
        Field field = class1.getDeclaredField("name");// 通过变量名称获得
        field.setAccessible(true);// 允许访问
        
        // 设置product2对象的name属性
        field.set(product2, "li");  //product2.name = "li";
        // 读取p对象的name属性
        System.out.println(field.get(product2));// 相当于p.name 结果li
    }

5、执行方法

// 执行方法
    @Test
    public void method5_5() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
        // 传统
        Product product = new Product();
        product.setName("tra");
        String name = product.getName();
        System.out.println(name);//tra
        
        // 反射
        Class class1  = Class.forName("p0123.Product");
        Object product2 = class1.newInstance();
        
        // 执行方法,需要获得方法对应Method对象
        // 方法由 名称和参数列表确定

        // setName : 名称setName 列表String.class
        Method setName = class1.getDeclaredMethod("setName", String.class);
        // 执行方法
        setName.invoke(product2, "zhangsan");// product2.setName("zhangsan");
        // getName : 名称 getName 参数列表 无
        Method getName  = class1.getDeclaredMethod("getName");
        // 执行方法
        String name2 = (String) getName.invoke(product2);
        System.out.println(name2);//zhangsan
    }

 

你可能感兴趣的:(java中的反射)