我有一些类A
:
public class A {
public A(String str) {
System.out.println("Create A instance: " + str);
}
public void methodA() {
System.out.println("#methodA1()");
}
}
还有我的类加载器实现:
public class MyClassLoader extends ClassLoader {
public MyClassLoader() {
super();
}
@Override
public synchronized Class<?> loadClass(String name)
throws ClassNotFoundException {
System.out.println("Load: " + name);
return super.loadClass(name);
}
}
现在我尝试更改当前线程中的默认类加载器:
import java.util.ArrayList;
import java.util.List;
public class ChangeLoaderTest {
public static void main(String[] args) {
// Save class loader so that we can restore later.
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
MyClassLoader newLoader = new MyClassLoader();
try {
// Set new classloader.
Thread.currentThread().setContextClassLoader(newLoader);
// My class.
A a = new A("1");
a.methodA();
// Standard Java class.
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(3);
} finally {
// Restore.
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
}
和ChangeLoaderTest
输出:
Create A instance: 1
#methodA1()
没有人
Load: ...
为什么?如何将 ClassLoader
更改为某个线程?
最佳答案
正如 Marko Topolnik 指出的 context classloader is for use by frameworks .要自己使用类加载器,您必须调用 loadClass("somepackage.A")
然后使用反射 API 创建 A 的新实例 (Class.newInstance()
).
您将无法在源代码中直接使用 A 或其方法,因为调用代码不知道 A - 它使用不同的类加载器。可以使用普通类加载器加载的 A 的接口(interface)或基类来避免反射。
interface AIF{
void someMethod();
}
class A implements AIF{
public void someMethod(){}
}
public void test(){
MyLoader loader = new MyLoader();
Class cla = loader.loadClass("A");
AIF a = (AIF) cla.newInstance();
a.someMethod();
}
关于Java 类加载器更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10192453/