2009-12-17 99 views
32

我有一些代码,调用..getClass()。getClassLoader()为null,为什么?

x = getClass().getClassLoader(); 

这虽然返回null。

当我从Eclipse启动相同的代码,但在命令行中,它返回一个类加载器。

我可以破解的代码做到这一点...

if (getClass().getClassLoader() == null) 
{ 
x = ClassLoader.getSystemClassLoader().getSystemResourceAsStream(loadedPropFileName); 
} 

都被编译并用相同的JVM上运行。 (我99.99%肯定)。

任何人有任何想法,为什么第一个将为类加载器返回null?

编辑:

我的问题是不“任何人有任何想法,为什么当通过Eclipse和命令行加载时一个类加载器启动时的同一类将返回null”

感谢Bootstap加载器必须在Eclipse中加载类的建议。我不知道为什么会发生这种情况。

回答

30

引述API doc

一些实施方案可使用null 表示引导类加载器。 如果此类是由引导类加载器加载的 ,则此方法将在此类 实现中返回null。

+3

是的,但如果执行方式相同,为什么命令行和Eclipse中的行为不同。我认为这是OP真正要求的...... – 2009-12-17 12:02:37

+1

如果他想知道与他所要求的不同的东西,为什么他不问他真正想知道的内容? – Bombe 2009-12-17 12:22:50

3

有一件事是肯定的,Eclipse比从命令行运行时有更深更复杂的classloader设置。如果你看到一个类的类加载器在一个类中出现差异,那么这是一个很可能的原因。

我不是究竟Eclipse是做知识渊博,但我认为这很可能是你的类是由引导类加载器加载在Eclipse中运行时,但Eclipse正在试图使它看起来这样。

一旦应用程序被引导,启动类加载器就是静态的,并且以后除非Eclipse重写了实现,否则不能向其中添加jar或类,在这种情况下,还有另一种可能的解释。

0

我有同样的问题。但解决它使用: -

<ClassName>.class.getClass().getResource(urlString); 

希望这会帮助别人......

7

这是如何工作的。每当JVM尝试加载任何类时,都会在以下条件下进行检查。

如果从Bootstrap ClassPath加载Class,即; jdk \ jre \ lib \ rt.jar,将调用BootStrap ClassLoader。

如果从扩展类路径加载类,即; jdk \ jre \ lib \ ext * .jar,扩展类加载器将被调用。

如果Class是从Application ClassPath加载的,即:如环境变量中指定的那样,调用Application ClassLoader。

因为Bootstrap ClassLoader没有在java中实现,所以它不是在c或C++中实现的,所以没有引用它就是为什么它返回null。但扩展和应用程序类加载器是用java编写的,因此您将获得[email protected][email protected]的引用。因此,如果你做了这样的事情,你可以使用System.out.println(String.class.getClassLoader()),因为这个类已经被BootStrap ClassLoader调用了,另一方面,如果你这样做对于Ext或App类路径中的类,您将分别得到 $ ExtClassLoader @ someHexValue和[email protected]

0

“如果此类由引导类加载器加载,则此方法将在此类实现中返回null。” - JavaDoc at getClassLoader()

为了安全起见,null类加载器是为系统类保留的,只能在Class.forName(String name,boolean initialize,ClassLoader loader)时使用。如果一个类有一个空ClassLoader,那么大多数安全检查都不会被执行。

相关问题