Java拾贝第十八天——反射之使用反射修改属性
1.Java拾贝第一天——数据类型与运算符杂记2.Java拾贝第二天——方法、方法的重载3.Java拾贝第二天——面向对象4.Java拾贝第三天——面向对象25.Java拾贝第四天——String和匿名对象6.Java拾贝第四天——面向对象37.Java拾贝第四天——动态绑定机制8.Java拾贝第五天——抽象和接口9.Java拾贝第五天——静态和代码块10.Java拾贝第五天——内部类11.Java拾贝第六天——匿名内部类12.Java拾贝第七天——包装类、BigInteger、BigDecimal13.Java拾贝第七天——异常14.Java拾贝第七天——throws和throw、自定义异常15.Java拾贝第七天——断言16.Java拾贝第八天(补档!)——访问修饰符,命名规范17.Java拾贝第八天——多线程的创建18.Java拾贝第八天——线程的状态和常用方法19.Java拾贝第九天——synchronized关键字20.Java拾贝第九天——泛型21.Java拾贝第十天——通配符与泛型22.Java拾贝第十一天——IO之File类23.Java拾贝第十一天——IO流之字节流24.Java拾贝第十一天——IO流之字符流25.Java拾贝第十一天——IO流之字节流复制图片、视频26.Java拾贝第十二天——IO流之打印流27.Java拾贝第十二天——System类28.Java拾贝第十二天——IO流之转换流29.Java拾贝第十二天——IO流之对象序列化与对象流30.Java拾贝第十三天——集合之List31.Java拾贝第十四天——集合之Set32.Java拾贝第十五天——集合之Iterator迭代器33.Java拾贝第十五天——集合之Map34.Java拾贝第十六天——集合之Queue、Stack35.Java拾贝第十六天——其他集合类Properties36.Java拾贝第十七天——反射之初识Class类37.Java拾贝第十七天——反射之认识反射相关类
38.Java拾贝第十八天——反射之使用反射修改属性
39.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最优。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~