Set private field value with reflection
To access a private field you need to set Field::setAccessible
to true. You can pull the field off the super class. This code works:
Class<?> clazz = Child.class;
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field");
f1.setAccessible(true);
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);
What is the shortest, best, cleanest way to set a private field via Reflection in Java?
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>
Get a private field via reflection, in Java
Change this line
name = (String) myStringField.get(obj.getClass());
to this
name = (String) myStringField.get(obj);
The get method requires an object to access the field of (unless it's a static field)
Set private field of package-private Class from outer package Class with reflection
I could see that the JarVerifier class does not have a default Constructor.
The constructor it has is something like this:-
public JarVerifier(byte rawBytes[]) {
manifestRawBytes = rawBytes;
sigFileSigners = new Hashtable<>();
verifiedSigners = new Hashtable<>();
sigFileData = new Hashtable<>(11);
pendingBlocks = new ArrayList<>();
baos = new ByteArrayOutputStream();
manifestDigests = new ArrayList<>();
}
So, you would have to get the non-default Constructor using reflection and then use it to create the instance. So, your code should be something like this:-
field.setBoolean(clazz.getConstructor(byte[].class).newInstance(new byte[1]), newValue);
Reference for JarVerifier class: https://github.com/netroby/jdk9-dev/blob/master/jdk/src/java.base/share/classes/java/util/jar/JarVerifier.java
Assumption: Your application has the required security permissions to modify access using reflection.
Further reference: Java: newInstance of class that has no default constructor
Setting private fields using Java Reflection
Get all the methods and find the matching one, which has type info about the parameters:
String name;
String value;
Method[] methods = Child.class.getMethods();
for (Method method : methods) {
if (!method.getName().equals(name))
continue;
Class<?> paramType = method.getParameterTypes()[0];
//You will have to figure how to convert the String value to the parameter.
method.invoke(child, paramType.cast(value)); // for example
}
Set value of private field
Try this (inspired by Find a private field with Reflection?):
var prop = s.GetType().GetField("id", System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance);
prop.SetValue(s, "new value");
My changes were to use the GetField
method - you are accessing a field and not a property, and to or NonPublic
with Instance
.
Reflection - getting private field value
val currentTrainingField = viewModel.javaClass.getDeclaredField("currentTraining")
currentTrainingField.isAccessible = true
val currentTraining = currentTrainingField.get(viewModel)
You relaxed the field's scope but you should access the value of that field on a specfic object, here viewModel
.
How to read the value of a private field from a different class in Java?
In order to access private fields, you need to get them from the class's declared fields and then make them accessible:
Field f = obj.getClass().getDeclaredField("stuffIWant"); //NoSuchFieldException
f.setAccessible(true);
Hashtable iWantThis = (Hashtable) f.get(obj); //IllegalAccessException
EDIT: as has been commented by aperkins, both accessing the field, setting it as accessible and retrieving the value can throw Exception
s, although the only checked exceptions you need to be mindful of are commented above.
The NoSuchFieldException
would be thrown if you asked for a field by a name which did not correspond to a declared field.
obj.getClass().getDeclaredField("misspelled"); //will throw NoSuchFieldException
The IllegalAccessException
would be thrown if the field was not accessible (for example, if it is private and has not been made accessible via missing out the f.setAccessible(true)
line.
The RuntimeException
s which may be thrown are either SecurityException
s (if the JVM's SecurityManager
will not allow you to change a field's accessibility), or IllegalArgumentException
s, if you try and access the field on an object not of the field's class's type:
f.get("BOB"); //will throw IllegalArgumentException, as String is of the wrong type
Related Topics
Consider Defining a Bean of Type 'Package' in Your Configuration [Spring-Boot]
How to Tell Jackson to Ignore a Property for Which I Don't Have Control Over the Source Code
Define a Fixed-Size List in Java
How Is Length Implemented in Java Arrays
Should Getters and Setters Be Synchronized
Getting Database Connection in Pure JPA Setup
Increase Http Post Maxpostsize in Spring Boot
Converting Decimal to Binary Java
Explicit Type Casting Example in Java
Java: Finding the Highest Value in an Array
Converting Array of Primitives to Array of Containers in Java
Increasing Heap Space in Eclipse: (Java.Lang.Outofmemoryerror)
Get Cell Value from Excel Sheet with Apache Poi
Copy All Values from Fields in One Class to Another Through Reflection
How to Correctly Use Custom Renderers to Paint Specific Cells in a Jtable