一个JVM实例只有一个方法区,里面放了一些类信息。但是bootstrap的路径 jre/classes下 有 study.test
appClassloader的路径下也有study.test现在我先用appClassloader加载 study.test,然后在用bootstrap加载study.test.这样方法区中就有两份 study.test类信息。但是它们的全限定名都是study.test,请问加载的时候是如何区分它们的?

解决方案 »

  1.   

    请问lz是怎么获取bootstrap类加载器的
      

  2.   

    每个classloader都有自己的命名空间,其装载的class都放在自己的命名空间里
      

  3.   

    只能访问一个,看你classpath怎么配置的,谁在前就先访问谁
    如果你的classpath=.;这么写,那当然先访问你自己的啦-------------------------------
    java菜鸟学堂QQ群144648357
      

  4.   


    在bootstrap路径下放个study.test那样就是用bootstrap加载的了,bootstrap为null获取了也没用
      

  5.   


    不管怎么说先谢谢你的回答,不过请你回答前先看清问题。这里不管classpath怎么配置,类加载器的祖先都是bootstrap
      

  6.   

    bootstrap 会优先加载这个类的但是如果你的类不是放在bootstrap中,而是一个单独的目录中,你可以新建两个URLClassLoader来加载这个类两次。你可以认为这两个是完全不同的类
      

  7.   

    类加载当然是在先,要不然怎么来执行楼主写的东西呢,
    但是jvm不至于什么类都加载吧,难道要将所有的类加载吗
    这里是他写的自定义类,jvm还不至于连楼主的类也加载进去吧
    除非楼主想覆盖掉原有的加载类,不过这样肯定是报错的
    因为如果能写出来,那也不会在这里混了,呵呵
      

  8.   

    由于父委托机制,同样一个class只能被加载一次,无论你把study.test放在哪个路径下,加载的时候都会自动向上寻找,最终还是会找到bootstrap,而此时如果能被bootstrap加载的话,就不会被它的子加载器加载,同理如果 
    bootstrap不能加载,就会向下寻找extend加载器然后系统加载器(应用加载器),关键是只能加载1次。即便是7楼说的用自己写的类加载器,它默认也是系统加载器的子加载器,一样会往上找,最终只能被一个定义类加载器加载
      

  9.   

    如果是这种情况,那么这两个加载器分别有自己的命名空间,两个study.test类在方法区内各自不同的命名空间里,互不影响,并且这两个同名的类在不同的运行时包。
      

  10.   

    你看清楚我的回复,我说的是【如果你的类不是放在bootstrap中,而是一个单独的目录中】,即父加载器是找不到这个类的,所以不会由父加载器加载到,因此会有两份类
    而且,使用父加载器只是默认的原则,除了bootstrap加载器无法跳过外,其它的可以跳过,由自己加载这个类(即使父加载器是可以加载这个类)
      

  11.   


    我在study.test类写了静态块代码,如果类第一次被加载静态块会被执行。所以我在"java.class.path"下放置study.test,删掉"sun.boot.class.path"下的study.test.这样study.test肯定被appclassloader加载。暂停10s,把study.test放到"sun.boot.class.path".再加载一次,发现静态块代码代码被执行了两次。说明这个类被加载了两次