gpt4 book ai didi

java - 通过新加载的类对静态变量所做的更改似乎不适用。 ( java )

转载 作者:行者123 更新时间:2023-11-30 02:08:21 25 4
gpt4 key购买 nike

我正在尝试一个 Reloader 类,它应该在使用时从磁盘重新加载该类。当出现一些我不太理解的东西时。

这就是静态变量 CHANGED在我的Test当我通过OtherClass的实例修改它时不会更新使用 Reloader 创建

这是我用来测试案例的代码。

测试.java:

import java.io.IOException;

public class Test {

public static boolean CHANGED = false;
static Test obj = new Test();

static void change() {
CHANGED = true;
System.out.println(CHANGED); // [1] It is clearly changed to true.
}

public static void main(String[] args) {
System.out.println(new OtherClass().toString2());
System.out.println(CHANGED);
try {
Object foo = reload();
System.out.println(foo);

} catch (InstantiationException | IllegalAccessException | IOException e) {
e.printStackTrace();
} finally {
System.out.println(CHANGED); // [2] But here it is false again.
}
}

public static Object reload() throws InstantiationException, IllegalAccessException, IOException {
Object foo = new Reloader().loadClass("OtherClass").newInstance();
return foo;
}

}

它调用 Reloader,它基本上创建一个类的新实例,从磁盘重新加载更改。还有更多魔法。公然“窃取”自用:How to force Java to reload class upon instantiation? .

Reloader.java:

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Reloader extends ClassLoader {

@Override
public Class<?> loadClass(String s) {
return findClass(s);
}

@Override
public Class<?> findClass(String s) {
try {
byte[] bytes = loadClassData(s);
return defineClass(s, bytes, 0, bytes.length);
} catch (IOException ioe) {
try {
return super.loadClass(s);
} catch (ClassNotFoundException ignore) {
}
ioe.printStackTrace(System.out);
return null;
}
}

private static byte[] loadClassData(String className) throws IOException {
File f = new File("bin/" + className.replaceAll("\\.", "/") + ".class");
int size = (int) f.length();
byte buff[] = new byte[size];
try (FileInputStream fis = new FileInputStream(f)) {
try (DataInputStream dis = new DataInputStream(fis)) {
dis.readFully(buff);
}
}
return buff;
}
}

OtherClass.java

public class OtherClass {

@Override
public String toString() {
Test.change();
return "OtherClass";
}

public String toString2() {
return "OLD";
}
}

因此,在 Test.java 文件中,有 2 条注释解释了我预期会发生什么,但实际发生了什么。[1] 这里变成了 true,这是预料之中的。[2]这里仍然是错误的,尽管代码肯定是在[1]之后执行的,而不是预期的。

我的问题是,为什么或如何该值没有改变?类加载器是否必须创建一个从其派生的全新“假”新测试类或其他类?

编辑:忘记显示调用它的位置。

最佳答案

由于该类是由不同的类加载器加载的,因此它被视为不同的类,并且将具有自己的值。

尝试不使用不同的类加载器,您将把CHANGED设置为true

关于java - 通过新加载的类对静态变量所做的更改似乎不适用。 ( java ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50805003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com