背景1:我们知道java中类加载机制采用双亲委托制机制,一个classloader要加载一个类,首先会委托他的上级加载器尝试加载,如果上级加载不成功才会自己加载。
背景2:我们自己的类的加载器是AppClassLoader,它的上级是ExtClassLoader。ExtClassLoader会在%JAVA_HONME%/jre/lib/ext目录中寻找、加载类。
背景3:我自己写了一个Test.java,编译后为Test.class。按背景2,Test的加载器是AppClassLoader,再根据背景1,它会首先委托ExtClassLoader去尝试加载。ExtClassLoader在%JAVA_HONME%/jre/lib/ext中找不到该类,故加载失败,所以最终还是会由AppClassLoader来加载Test.class。
问题:
可是,如果我把编译好的Test.class打成jar包,放到%JAVA_HONME%/jre/lib/ext目录中,那么当AppClassLoader委托给ExtClassLoader加载时,ExtClassLoader会加载成功吗?
这个问题困扰我的地方在于,按照背景2,貌似的确应该由ExtClassLoader去加载Test。但我感觉这违反直觉,我要运行的是本地的Test.class,但是JVM却加载了另一个Test.class(%JAVA_HONME%/jre/lib/ext下),那么本地这个Test.class还有什么意义?到底哪个class里面的代码会执行呢?
------解决方案--------------------
你IDE用的jdk和系统用的是一个吗?
------解决方案--------------------
都没搞明白你main方法是写在哪里的? 你到底想测试什么。
首先类只有被用到才会被加载, main方法定义的那个类肯定会被加载。
所以如果你定义main方法的那个类里面只有一句输出,根本都不会加载ext下面的东西。
再有类加载是按照全限定名来的, 如果你jar包里面的Test类跟测试的Test类全限定名都一样的话,且里面都定义了main方法, 我可以负责任的告诉你,jvm只会加载运行ext下面的Test.main, 而你自己的Test类根本都不会被加载