我有一个关于类加载概念的问题.如何在JVM中加载.class文件两次.我也在编写一段代码,我已经写完了这个代码.
1)装载机1代码
public class MyClassLoader extends ClassLoader {
public MyClassLoader(){
super(MyClassLoader.class.getClassLoader());
}
public Class loadClass(String classname){
try {
return super.loadClass(classname);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
}
2)装载机2代码
public class AnotherClassLoader extends ClassLoader {
public AnotherClassLoader(){
super(AnotherClassLoader.class.getClassLoader());
}
public Class loadClass(String classname){
try {
return super.loadClass(classname);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
}
3)现在我使用这两个不同的类加载器加载一个名为A的类.我想操作classA1 == newClassA应该返回false.这是代码:
public static void main(String[] args) {
MyClassLoader loader1 = new MyClassLoader();
AnotherClassLoader newLoader = new AnotherClassLoader();
System.out.println("Load with Custom Class Loader instance");
Class classA1 = loader1.loadClass("com.hitesh.coreJava.A");
System.out.println("Class Loader:::"+classA1.getClassLoader());
Class newClassA = newLoader.loadClass("com.hitesh.coreJava.A");
System.out.println("Class Loader:::"+newClassA.getClassLoader());
System.out.println(classA1==newClassA);
System.out.println(classA1.hashCode() + " , " + newClassA.hashCode());
}
Run Code Online (Sandbox Code Playgroud)
4)执行上述代码的结果:
使用自定义类加载器实例加载类加载器::: sun.misc.Launcher$AppClassLoader@11b86e7类加载器::: sun.misc.Launcher$AppClassLoader@11b86e7 true 1641745,1641745
你能解释一下吗?
Both classloaders start the lookup in their parent classloader (that's what the super() call is about). So actually the super classloader loads it in both cases.
You can try this:
String pathToJar = "C:\\path\\to\\my.jar";
String className = "com.mypackage.ClassA";
URLClassLoader cl1 = new URLClassLoader(new URL[] { new URL(pathToJar) });
URLClassLoader cl2 = new URLClassLoader(new URL[] { new URL(pathToJar) });
Class<?> c1 = cl1.loadClass(className);
Class<?> c2 = cl2.loadClass(className);
System.out.println(c1);
System.out.println(c2);
System.out.println(c1==c2 ? "Parent classloader loads" : "Parent classloader does not load");
cl1.close();
cl2.close();
Run Code Online (Sandbox Code Playgroud)
Make sure that my.jar is NOT on your classpath.
试试这个
public class Test1 {
static class TestClassLoader1 extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (!name.equals("Test1")) {
return super.loadClass(name);
}
try {
InputStream in = ClassLoader.getSystemResourceAsStream("Test1.class");
byte[] a = new byte[10000];
int len = in.read(a);
in.close();
return defineClass(name, a, 0, len);
} catch (IOException e) {
throw new ClassNotFoundException();
}
}
}
public static void main(String[] args) throws Exception {
Class<?> c1 = new TestClassLoader1().loadClass("Test1");
Class<?> c2 = new TestClassLoader1().loadClass("Test1");
System.out.println(c1);
System.out.println(c2);
System.out.println(c1 == c2);
}
}
Run Code Online (Sandbox Code Playgroud)
产量
class Test1
class Test1
false
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您都使用相同的类加载器来执行加载。你有两个类加载器,但每个都只调用 super.loadClass() ,它委托给同一个父类加载器,即 AppClassLoader。
| 归档时间: |
|
| 查看次数: |
13640 次 |
| 最近记录: |