Java 使用反射设置字段值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24094871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set field value with reflection
提问by user2749903
I'm working with one project which is not opensource and I need to modify one or more its classes.
我正在处理一个非开源项目,我需要修改它的一个或多个类。
In one class is following collection:
在一个类中是以下集合:
private Map<Integer, TTP> ttp = new HashMap<>();
All what I need to do is use reflection and use concurrenthashmap here. I've tried following code but it doesnt work.
我需要做的就是在这里使用反射和使用 concurrenthashmap。我试过下面的代码,但它不起作用。
Field f = ..getClass().getDeclaredField("ttp");
f.setAccessible(true);
f.set(null, new ConcurrentHashMap<>());
采纳答案by Visruth
Hope this is something what you are trying to do :
希望这是您正在尝试做的事情:
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
private Map ttp = new HashMap();
public void test() {
Field declaredField = null;
try {
declaredField = Test.class.getDeclaredField("ttp");
boolean accessible = declaredField.isAccessible();
declaredField.setAccessible(true);
ConcurrentHashMap<Object, Object> concHashMap = new ConcurrentHashMap<Object, Object>();
concHashMap.put("key1", "value1");
declaredField.set(this, concHashMap);
Object value = ttp.get("key1");
System.out.println(value);
declaredField.setAccessible(accessible);
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String... args) {
Test test = new Test();
test.test();
}
}
It prints :
它打印:
value1
回答by Braj
It's worth reading Oracle Java Tutorial - Getting and Setting Field Values
Field#set(Object object, Object value)sets the field represented by this Field
object on the specified objectargument to the specified new value.
Field#set(Object object, Object value)将指定对象参数Field
上此对象表示的字段设置为指定的新值。
It should be like this
应该是这样的
f.set(objectOfTheClass, new ConcurrentHashMap<>());
You can't set any value in null
Object If tried then it will result in NullPointerException
您不能在null
Object 中设置任何值如果尝试,则会导致NullPointerException
Note:Setting a field's value via reflection has a certain amount of performance overheadbecause various operations must occur such as validating access permissions. From the runtime's point of view, the effects are the same, and the operation is as atomic as if the value was changed in the class code directly.
注意:通过反射设置字段的值有一定的性能开销,因为必须进行各种操作,例如验证访问权限。从运行时的角度来看,效果是一样的,而且操作是原子的,就好像直接在类代码中更改了值一样。
回答by Alex Burdusel
The method below sets a field on your object even if the field is in a superclass
即使该字段在超类中,下面的方法也会在您的对象上设置一个字段
/**
* Sets a field value on a given object
*
* @param targetObject the object to set the field value on
* @param fieldName exact name of the field
* @param fieldValue value to set on the field
* @return true if the value was successfully set, false otherwise
*/
public static boolean setField(Object targetObject, String fieldName, Object fieldValue) {
Field field;
try {
field = targetObject.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
field = null;
}
Class superClass = targetObject.getClass().getSuperclass();
while (field == null && superClass != null) {
try {
field = superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
superClass = superClass.getSuperclass();
}
}
if (field == null) {
return false;
}
field.setAccessible(true);
try {
field.set(targetObject, fieldValue);
return true;
} catch (IllegalAccessException e) {
return false;
}
}
回答by VK321
You can try this:
你可以试试这个:
//Your class instance
Publication publication = new Publication();
//Get class with full path(with package name)
Class<?> c = Class.forName("com.example.publication.models.Publication");
//Get method
Method method = c.getDeclaredMethod ("setTitle", String.class);
//set value
method.invoke (publication, "Value to want to set here...");
回答by Javad Khosravi
You can try this:
你可以试试这个:
static class Student {
private int age;
private int number;
public Student(int age, int number) {
this.age = age;
this.number = number;
}
public Student() {
}
}
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
Student student1=new Student();
// Class g=student1.getClass();
Field[]fields=student1.getClass().getDeclaredFields();
Field age=student1.getClass().getDeclaredField("age");
age.setAccessible(true);
age.setInt(student1,13);
Field number=student1.getClass().getDeclaredField("number");
number.setAccessible(true);
number.setInt(student1,936);
for (Field f:fields
) {
f.setAccessible(true);
System.out.println(f.getName()+" "+f.getInt(student1));
}
}
}
}