使用 ClassLoader 加载的 class 无法访问已更改的变量
A class loaded with ClassLoader don't have access to changed variables
我有一个问题:
有一个从外部 .java 文件
编译的 class
private static Class<?> LoadedClass;
private static Object LoadedClassInstance;
public static Method LoadedMethod;
[SKIP]
private static Path compileSource(Path javaFile) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, javaFile.toFile().getAbsolutePath());
return javaFile.getParent().resolve("LoadedClass.class");
}
private static void runClass(Path javaClass)
throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
URL classUrl = javaClass.getParent().toFile().toURI().toURL();
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{classUrl});
LoadedClass = Class.forName("LoadedClass", true, classLoader);
在这个class中有一个方法:
LoadedClassInstance = LoadedClass.getDeclaredConstructor().newInstance();
LoadedMethod = LoadedClass.getDeclaredMethod("DoTheMethod");
}
这里是调用加载方法的静态方法:
public static void CallLoadedMethod() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
LoadedMethod.invoke(LoadedClassInstance);
}
加载的方法调用另一个方法:
import MyApp.MyClass1;
[SKIP]
public static void DoTheMethod() {
System.out.println("Your number is : "+MyClass1.Number);
}
我还有两个 class 可以互动:
// MyClass1
public static int Number = 5;
public class MyClass1 {
// DoSomeStuff
}
// MyClass2
public class MyClass2 {
public static void SetTheNumberTo(int number){
MyClass1.Number = number;
System.out.println("Your NEW number is : "+MyClass1.Number);
}
}
这是 Loaded 方法调用示例:
MyClass2.SetTheNumberTo(10);
Class_Loader.DoTheMethod();
当我通过 Eclipse 运行 我的应用程序时,我得到:
Your NEW number is : 10
Your number is : 10
但是当我将它编译为 运行nable .jar 时,我得到了另一个结果:
Your NEW number is : 10
Your number is : 5
问题来了:我做错了什么?
如果两个 class 对象具有相同的名称和相同的 ClassLoader,则它们是相同的。您已加载 两个不同的 classes,每个都命名为 MyClass1
.
MyClass1.Number
在你的 Class_Loader
不同于 MyClass1.Number
在你的主程序的 ClassLoader 中从 MyClass2 调用。它们不是同一个字段,因为它们不在同一个 class.
我有一个问题: 有一个从外部 .java 文件
编译的 class private static Class<?> LoadedClass;
private static Object LoadedClassInstance;
public static Method LoadedMethod;
[SKIP]
private static Path compileSource(Path javaFile) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, javaFile.toFile().getAbsolutePath());
return javaFile.getParent().resolve("LoadedClass.class");
}
private static void runClass(Path javaClass)
throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
URL classUrl = javaClass.getParent().toFile().toURI().toURL();
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{classUrl});
LoadedClass = Class.forName("LoadedClass", true, classLoader);
在这个class中有一个方法:
LoadedClassInstance = LoadedClass.getDeclaredConstructor().newInstance();
LoadedMethod = LoadedClass.getDeclaredMethod("DoTheMethod");
}
这里是调用加载方法的静态方法:
public static void CallLoadedMethod() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
LoadedMethod.invoke(LoadedClassInstance);
}
加载的方法调用另一个方法:
import MyApp.MyClass1;
[SKIP]
public static void DoTheMethod() {
System.out.println("Your number is : "+MyClass1.Number);
}
我还有两个 class 可以互动:
// MyClass1
public static int Number = 5;
public class MyClass1 {
// DoSomeStuff
}
// MyClass2
public class MyClass2 {
public static void SetTheNumberTo(int number){
MyClass1.Number = number;
System.out.println("Your NEW number is : "+MyClass1.Number);
}
}
这是 Loaded 方法调用示例:
MyClass2.SetTheNumberTo(10);
Class_Loader.DoTheMethod();
当我通过 Eclipse 运行 我的应用程序时,我得到:
Your NEW number is : 10
Your number is : 10
但是当我将它编译为 运行nable .jar 时,我得到了另一个结果:
Your NEW number is : 10
Your number is : 5
问题来了:我做错了什么?
如果两个 class 对象具有相同的名称和相同的 ClassLoader,则它们是相同的。您已加载 两个不同的 classes,每个都命名为 MyClass1
.
MyClass1.Number
在你的 Class_Loader
不同于 MyClass1.Number
在你的主程序的 ClassLoader 中从 MyClass2 调用。它们不是同一个字段,因为它们不在同一个 class.