嗨,我已经使用过 Java 中的 Reflection。但是如果您使用 java 标准(例如注入私有字段),您必须编写大量代码才能完成工作。
在 Java 对象中注入私有字段的最短方法是什么?广泛使用和生产就绪的库中是否有实现?
如果不使用外部库,您需要:
Field
实例如下:
Field f1 = obj.getClass().getDeclaredField("field");
f1.setAccessible(true);
f1.set(obj, "new Value");
“单线”
FieldUtils.writeField(Object target, String fieldName, Object value, boolean forceAccess)
如果您的项目使用 Apache Commons Lang 通过反射设置值的最短方法是使用类 'org.apache.commons.lang3.reflect.FieldUtils' 中的静态方法 'writeField'
以下简单示例显示了带有 paymentService 字段的 Bookstore-Object。该代码显示了如何使用不同的值两次设置私有字段。
import org.apache.commons.lang3.reflect.FieldUtils;
public class Main2 {
public static void main(String[] args) throws IllegalAccessException {
Bookstore bookstore = new Bookstore();
//Just one line to inject the field via reflection
FieldUtils.writeField(bookstore, "paymentService",new Paypal(), true);
bookstore.pay(); // Prints: Paying with: Paypal
//Just one line to inject the field via reflection
FieldUtils.writeField(bookstore, "paymentService",new Visa(), true);
bookstore.pay();// Prints Paying with: Visa
}
public static class Paypal implements PaymentService{}
public static class Visa implements PaymentService{}
public static class Bookstore {
private PaymentService paymentService;
public void pay(){
System.out.println("Paying with: "+ this.paymentService.getClass().getSimpleName());
}
}
}
您可以通过mavencentral获取lib:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
如果您使用
Spring Framework
,则有一个名为 ReflectionUtils
的 utils 类
这是一种将值注入私有字段的方法。
根据:
findField(Class<?> clazz, String name, Class<?> type)
和
setField(Field field, @Nullable Object target, @Nullable Object value)
您可以写:
final Field field = ReflectionUtils.findField(Foo.class, "name", String.class)
ReflectionUtils.setField(field, targetObject, "theNewValue")
如果这是出于测试目的,
ReflectionTestUtils
也为您提供了一些方法。
您可以在文档中找到所有内容这里
希望有帮助。
我要做的就是使其成为一个辅助方法。
public static void changeField(Class cc, String field, String newValue) throws NoSuchFieldException, IllegalAccessException {
Field f = cc.getDeclaredField(field);
f.setAccessible(true);
f.set(cc, newValue);
f.setAccessible(false);
}
并像下面这样称呼它
changeField(cc, "field", "newValue");