Java拾贝第十八天——反射之使用反射修改属性

在认识反射相关类中,可以通过Class类的方法来获取一个Filed类访问一个类的属性。当然也提供了直接通过Field类修改属性。

Filed类常用方法如下:

方法 类型 描述
public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException 普通方法 获取某实例的属性值
public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException 普通方法 设置某实例的属性值
public boolean isAccessible() 普通方法 能否被外部直接访问
public void setAccessible(boolean flag) throws SecurityException 普通方法 设置能否被外部直接访问

public Object get(Object obj)

获取某实例的属性值

栗子:

package moudle2;

import java.lang.reflect.Field;

public class Test18 {
    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("moudle2.P");//通过反射获取P类对象
            Field field = clazz.getField("x");//通过反射获取公开x属性对象
            Object instance = clazz.newInstance();//创建P类实例

            System.out.println(field.get(instance));//等价于 System.out.println(instance.i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class P{
    public double x = 20;
}

程序运行结果:

20.0

注意上述栗子中field指向的是P类中的x属性。

再次强调反射就是在运行过程中可以知晓任意类的任意信息。

public void set(Object obj, Object value)

设置某实例的属性值

栗子:

package moudle2;

import java.lang.reflect.Field;

public class Test18 {
    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("moudle2.P");
            Field field = clazz.getField("x");//通过反射获取公开x属性对象
            Object instance = clazz.newInstance();//创建P类实例

            field.set(instance,49.99);//通过反射设置属性值 等价于 instance.x=49.99
            System.out.println(field.get(instance));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class P{
    public double x = 20;
}

程序运行结果:

49.99

反射真的太神奇辣!

可上述两个栗子都直接访问的属性,这并不符合封装性。

至此,其他两个方法登场!

public boolean isAccessible()

属性能否被外部直接访问

栗子:

package moudle2;

import java.lang.reflect.Field;

public class Test18 {
    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("moudle2.P");
            //clazz.getField("i");私有属性无法被getField()方法获取
            Field field = clazz.getDeclaredField("i");//通过反射获取公开i属性对象

            if (field.isAccessible()){
                System.out.println("该属性可以被直接访问");
            }else {
                System.out.println("该属性无法被直接访问");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class P{
    public double x = 20;
    private int i = 10;
}

程序运行结果:

该属性无法被直接访问

public void setAccessible(boolean flag)

设置属性能否被外部直接访问

栗子:

package moudle2;

import java.lang.reflect.Field;

public class Test18 {
    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("moudle2.P");
            Object o = clazz.newInstance();
            Field field = clazz.getDeclaredField("i");//通过反射获取公开x属性对象
            field.setAccessible(true);//设置可以被外部直接访问

            System.out.println("i属性值"+field.get(o));
            field.set(o,50);
            System.out.println("set后 i属性值"+field.get(o));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class P{
    public double x = 20;
    private int i = 10;
}

程序运行结果:

i属性值10
set后 i属性值50

虽然修改成功了,但这种形式的修改属性破坏了封装性。

开发中不要直接操作属性!!!还是使用setter和getter最优。

posted @ 2023-11-06 17:56  rowbed  阅读(93)  评论(0编辑  收藏  举报