Hi I've already worked with Reflection in Java. But if you are using the java standards (e.g. injecting a private field) you have to write a lot of code to get the job done.
What is the shortest way to inject a private field in a Java Object? Are there implementations in widely used and production ready libraries?
Without using external libraries you need to:
Field
instanceAs follow:
Field f1 = obj.getClass().getDeclaredField("field");
f1.setAccessible(true);
f1.set(obj, "new Value");
The "One-Liner"
FieldUtils.writeField(Object target, String fieldName, Object value, boolean forceAccess)
If your Project uses Apache Commons Lang the shortest way to set a value via reflection is to use the static Method 'writeField' in the class 'org.apache.commons.lang3.reflect.FieldUtils'
The following simple example shows a Bookstore-Object with a field paymentService. The code shows how the private field is set two times with a different value.
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());
}
}
}
You can get the lib via maven central:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
If you're using the Spring Framework
, there is an utils class named ReflectionUtils
Here is a way to inject a value into a private field.
According to :
findField(Class<?> clazz, String name, Class<?> type)
and
setField(Field field, @Nullable Object target, @Nullable Object value)
You can write:
final Field field = ReflectionUtils.findField(Foo.class, "name", String.class)
ReflectionUtils.setField(field, targetObject, "theNewValue")
It is certainly not the shortest way to write this but it is shorter than the basic JDK tools to do this and I trusts people who are developing Spring so I am confident enough. Just be sure you actually really need reflection before doing this.
Plus if this is for a testing purpose, there is ReflectionTestUtils
that provides you some methods too.
You'll find everything in the docs here
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With