Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 尝试在运行时使用反射更改属性的值会导致NullPointerException_Java_Reflection - Fatal编程技术网

Java 尝试在运行时使用反射更改属性的值会导致NullPointerException

Java 尝试在运行时使用反射更改属性的值会导致NullPointerException,java,reflection,Java,Reflection,我正在为一个类编写单元测试: import java.io.File; public class MyLogger { private final File logFile = new File("default"); public File getLogFile() { return this.logFile; } } 我想从另一个类中更改分配给logFile的值,例如: import java.io.File; import java.lang

我正在为一个类编写单元测试:

import java.io.File;

public class MyLogger {

    private final File logFile = new File("default");

    public File getLogFile() {
        return this.logFile;
    }
}
我想从另一个类中更改分配给
logFile
的值,例如:

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

    public static void main(String[] args) throws NoSuchFieldException, SecurityException, Exception {

        MyLogger logger = new MyLogger();
        System.out.println(logger.getLogFile());

        setFinal(MyLogger.class.getDeclaredField("logFile"), new File("changed"));
        System.out.println(logger.getLogFile());
    }

    private static void setFinal(Field field, Object newValue) throws Exception {
        field.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        field.set(null, newValue);
    }
}
但我得到的输出/异常如下:

default
Exception in thread "main" java.lang.NullPointerException
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:57)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
    at java.lang.reflect.Field.set(Field.java:764)
    at Main.setFinal(Main.java:23)
    at Main.main(Main.java:12)

您正在使用
字段。以错误的方式设置
方法。您需要提供必须在其上设置新字段值的对象,在您的代码中,它应该是
记录器
对象,但您正在传递
null

public static void main(String[] args) throws NoSuchFieldException, SecurityException, Exception {

    MyLogger logger = new MyLogger();
    System.out.println(logger.getLogFile());

    setFinal(logger, MyLogger.class.getDeclaredField("logFile"), new File("changed"));
    System.out.println(logger.getLogFile());
}

private static void setFinal(MyLogger logger, Field field, Object newValue) throws Exception {
    field.setAccessible(true);

    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

    field.set(logger, newValue);
}
这与
字段的方法签名一致。从以下位置设置

设置指定字段上此字段对象表示的字段 对象参数设置为指定的新值


我可以使用java.lang.reflect.Method这样做检查下面的代码是否有助于解决您的问题

Method method = MyLogger.getClass().getDeclaredMethod("getLogFile");
            method.setAccessible(true);
在getDeclaredMethod中,您需要给出完整的方法名