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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:07:07  来源:igfitidea点击:

Set field value with reflection

javareflectionfield

提问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

值得一读Oracle Java 教程 - 获取和设置字段值

Field#set(Object object, Object value)sets the field represented by this Fieldobject 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 nullObject If tried then it will result in NullPointerException

您不能在nullObject 中设置任何值如果尝试,则会导致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));

    }
}

}

}