JAVA反射-反射中对属性的操作

1. 获取对象的属性

对象的属性,在反射中是 Field 对象

1.0 准备一个类

package com.northcastle.classtry;

/**
 * author : NorthCastle
 * createTime:2021/9/20
 */
public class Car {
    //1.公有属性
    public String name = "测试的一辆车";
    public Integer age = 1;
    //2.私有属性
    private String brand;
    private String price;
    private static String a;
    //3.无参构造
    public Car() { }
    //4.有参构造
    public Car(String name, Integer age, String brand, String price) {
        this.name = name;
        this.age = age;
        this.brand = brand;
        this.price = price;
    }
    //5.getter/setter 方法
    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }
    // 6.toString() 方法
    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", brand='" + brand + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}

1.1 获取对象的属性列表

方法一 : getFields() : 仅能获取到public 类型的属性
方法二 : getDeclaredFields() : 可以获取到所有的类中声明的属性,公有、私有都可以

public class ApplicationForField {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //1.获取Car类的Class对象
        String classFullPath = "com.northcastle.classtry.Car";
        Class<?> clazz = Class.forName(classFullPath);

        //2.反射创建Car类的对象
        Object o = clazz.newInstance();
        Car car = (Car) o;

        //3.获取Class对象中的属性列表
        Field[] fields = clazz.getFields(); // 只能获取到 public 的属性
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("==============================");
        Field[] declaredFields = clazz.getDeclaredFields(); // 可以获取到 所有的属性
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
    }
}
# 运行结果:
public java.lang.String com.northcastle.classtry.Car.name
public java.lang.Integer com.northcastle.classtry.Car.age
==============================
public java.lang.String com.northcastle.classtry.Car.name
public java.lang.Integer com.northcastle.classtry.Car.age
protected java.lang.String com.northcastle.classtry.Car.a
private java.lang.String com.northcastle.classtry.Car.brand
private java.lang.String com.northcastle.classtry.Car.price

1.2 获取对象的指定属性

方法一 : getField(String name) : 仅能获取public类型名为name 的属性
方法二: getDeclareField(String name) : 获取类中声明的名为 name 的属性

public class ApplicationForField {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //1.获取Car类的Class对象
        String classFullPath = "com.northcastle.classtry.Car";
        Class<?> clazz = Class.forName(classFullPath);

        //2.反射创建Car类的对象
        Object o = clazz.newInstance();
        Car car = (Car) o;
        
        //4.获取指定name的属性
        try {
            Field name = clazz.getField("name"); // public 的正常获取
            System.out.println("getField(name) : "+name);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            Field brand = clazz.getField("brand");// private 的,获取不到
            System.out.println("getField(brand) : "+brand);
        } catch (NoSuchFieldException e) {
            System.out.println("getField(brand) : 无法获取brand 属性!");
            e.printStackTrace();
        }
        try {
            Field brand = clazz.getDeclaredField("brand");
            System.out.println("getDeclareField(brand) : "+brand);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }


    }
}
getField(name) : public java.lang.String com.northcastle.classtry.Car.name

getField(brand) : 无法获取brand 属性!
java.lang.NoSuchFieldException: brand
	at java.lang.Class.getField(Class.java:1703)
	at com.northcastle.classtry.ApplicationForField.main(ApplicationForField.java:39)
	
getDeclareField(brand) : private java.lang.String com.northcastle.classtry.Car.brand

1.3 修改对象的公有属性的值

可以直接使用get方法获取指定对象的属性值
可以直接使用set方法设置指定对象的属性值

public class ApplicationForField {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //1.获取Car类的Class对象
        String classFullPath = "com.northcastle.classtry.Car";
        Class<?> clazz = Class.forName(classFullPath);

        //2.反射创建Car类的对象
        Object o = clazz.newInstance();
        Car car = (Car) o;
        
        //5.修改 car 对象的 name 的值(public的属性)
        Field nameField = clazz.getDeclaredField("name");
        // 获取car的name属性(关键操作)
        Object name = nameField.get(car); 
        System.out.println(car); // 修改前的car
        
        //将car的name属性进行修改(关键操作)
        nameField.set(car,"测试修改name");
        System.out.println(car); // 修改后的car
        
    }
}

#运行结果
Car{name='测试的一辆车', age=1, brand='null', price='null'}
Car{name='测试修改name', age=1, brand='null', price='null'}

1.4 修改对象的私有属性的值

私有属性必须设置setAccessible(true);后才可以继续使用 get/set方法

public class ApplicationForField {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //1.获取Car类的Class对象
        String classFullPath = "com.northcastle.classtry.Car";
        Class<?> clazz = Class.forName(classFullPath);

        //2.反射创建Car类的对象
        Object o = clazz.newInstance();
        Car car = (Car) o;

        //6.修改 car 对象的 brand 的值(private的属性)
        Field brandField =  clazz.getDeclaredField("brand");
        // 私有属性必须设置为 可操作的才可以执行get/set操作
        brandField.setAccessible(true);

        Object brand = brandField.get(car);// 获取 car 的 brand属性
        System.out.println(car);

        brandField.set(car,"测试修改brand");
        System.out.println(car);
    }
}
# 运行结果
Car{name='测试修改name', age=1, brand='null', price='null'}
Car{name='测试修改name', age=1, brand='测试修改brand', price='null'}

1.5 获取属性的信息

1.获取属性的修饰符 getModifiers() : 以int形式返回修饰符
【default = 0 ; public = 1; private = 2; protected = 4; static = 8;final = 16】
返回的值是 修饰符之和: 例如 private static String name;
则 2 + 8 = 10,getModifiers() 的返回值是 10;
2.以Class形式返回属性的类型 : getType()

public class ApplicationForField {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //1.获取Car类的Class对象
        String classFullPath = "com.northcastle.classtry.Car";
        Class<?> clazz = Class.forName(classFullPath);
        
        // 7.获取属性的修饰符和类型
        // private static String a;
        // 2 + 8 = 10
        Field a = clazz.getDeclaredField("a");
        int modifiers = a.getModifiers();
        Class<?> type = a.getType();
        System.out.println("修饰符是 : "+modifiers);
        System.out.println("类型是 : "+type);

    }
}
#运行结果
修饰符是 : 10
类型是 : class java.lang.String

2.完成

Congratulations!
You are one step closer to success!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值