java - 尝试在运行时使用反射更改属性的值会导致 NullPointerException
问题描述
我有一门课要写单元测试:
import java.io.File;
public class MyLogger {
private final File logFile = new File("default");
public File getLogFile() {
return this.logFile;
}
}
我想logFile
从另一个类中更改分配给的值,例如:
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Main {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, Exception {
MyLogger logger = new MyLogger();
System.out.println(logger.getLogFile());
setFinal(MyLogger.class.getDeclaredField("logFile"), new File("changed"));
System.out.println(logger.getLogFile());
}
private static void setFinal(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
但我得到以下输出/异常:
default
Exception in thread "main" java.lang.NullPointerException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:57)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:764)
at Main.setFinal(Main.java:23)
at Main.main(Main.java:12)
解决方案
您Field.set
以错误的方式使用该方法。您需要提供必须设置新字段值的对象,在您的代码中它应该是logger
对象,但您正在传递null
:
public static void main(String[] args) throws NoSuchFieldException, SecurityException, Exception {
MyLogger logger = new MyLogger();
System.out.println(logger.getLogFile());
setFinal(logger, MyLogger.class.getDeclaredField("logFile"), new File("changed"));
System.out.println(logger.getLogFile());
}
private static void setFinal(MyLogger logger, Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(logger, newValue);
}
这是根据文档中的Field.set
方法签名:
将指定对象参数上的此 Field 对象表示的字段设置为指定的新值。
推荐阅读
- ios - 在本地存储 JSON 数据并在 tableView 中呈现的问题
- bash - 奇怪的 gdate 结果
- facebook-graph-api - 使用 Facebook 提供的 Whatsapp api 发送消息有定价吗?
- postgresql - 如何在 postgres 过程中通过 arg 文本更改架构
- python - 我正在尝试使用 python 调整图像包的大小。但它只调整了 5 张图片的大小而不是全部
- python-3.x - 重塑excel数据
- java - Java Google App Engine 不会通过 Mailgun SMTP 发送电子邮件
- vue.js - 在 nativescript-vue 中以编程方式设置事件监听器
- ios - decoder.decode 设置有效的 iso8601 日期为 nil
- python - 获取给定语言的 pyqt5 qlabel 小部件翻译(不显示)