证明:同一个JVM里面一个Class可以被load多次

对CLASSLOADER有过研究的人都知道,JVM使用CLASSLOADER在JVM中分隔出许多命名空间,不同的命名空间中的类是不“互见的”,这个“不互见”的意思是彼此不知道对方的存在,比如classloader1加载类A,在classloader2所构建的命名空间里面类就不知道的。classloader2因为不知道classloader2加载了A,所以它自己也可以以自己的方式来加载“另一个”类A。这样其实,在JVM内就存在两个Class A了。、

上面的理论其实在看过“深入JVM”后就知道了。最近又翻了翻这本书,想起两年前与同事说的那句话“JVM可以loader两个同样的类,那你证明下呀”,当时没当回事,反正也是懵懵懂懂证明不了,避而不谈。现在呢,有时间也有能力了,那就来证明下吧。

这个证明的逻辑是:

因为class在被加载的时候,其static域会被初始化,那么一个类被加载两次加载进jvm的话,那么static域就会被初始化两次。

那现在只要证明static的域是可以被初始化两次就可以了。那怎么证明呢?

只要每次在初始化的时候能给static域赋上不同的值,区分出来,在特定的时候打印出来

就可以了。

看下下面的代码片段,事情可能就清楚了。

被加载的类 IntProducer:

import java.util.Random;

public class IntProducer
{
//用随机值来加载静态域赋值,如果被加载两次age应该会是不同的值
public static int age = getRandom();

public static int getRandom()
{
Random ran = new Random(System.nanoTime());
int rand = ran.nextInt(10);
System.out.println("IntProducer 被加载,产生随机数:"+rand);
return rand;

}

}


用于加载IntProducer的类:


public class LoaderSample4
{

public static void main(String[] args) throws Exception
{
System.out.println(LoaderSample4.class.getClassLoader());


URL[] us =
{ new URL("file://D:/") };

ClassLoader loader1 = new URLClassLoader(us);
Class c1 = loader1.loadClass("IntProducer");

System.out.println(c1.getClassLoader()+":"+c1.getField("age").getInt(c1));

//再加载一次
ClassLoader loader2 = new URLClassLoader(us);
Class c2 = loader2.loadClass("IntProducer");
System.out.println(c2.getClassLoader()+":"+c2.getField("age").getInt(c2));

}

}

你可能感兴趣的:(证明:同一个JVM里面一个Class可以被load多次)