繁体   English   中英

getClass().getClassLoader() 是null,为什么?

[英]getClass().getClassLoader() is null, why?

我有一些代码可以调用..

x = getClass().getClassLoader();

不过,这会返回 null。

当我不是从 Eclipse 而是从命令行启动相同的代码时,它会返回一个类加载器。

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

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

两者都使用相同的 JVM 编译和运行。(我有 99.99% 的把握)。

任何人都知道为什么第一个会为类加载器返回 null?

编辑:

我的问题是“任何人都知道为什么相同的 class 在通过 Eclipse 启动时会返回 null 而在从命令行加载时会返回 class 加载程序。”

感谢 Bootstap 加载程序必须在 Eclipse 中加载 class 的建议。我不知道为什么会这样。

引用API 文档

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

这就是它的工作原理。 每当 JVM 尝试加载任何类时,它都会检查以下条件。

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

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

如果 Class 是从 Application ClassPath 加载的,即; 如环境变量中所指定,应用程序类加载器被调用。

由于 Bootstrap ClassLoader 没有在 java 中实现,它要么是在 c 或 c++ 中实现的,所以没有对它的引用,这就是它返回 null 的原因。 但是 Extension 和 Application 类 Loader 是用 java 编写的,因此您将获得 sun.misc.Launcher$ExtClassLoader@someHexValue 和 sun.misc.Launcher$AppClassLoader@someHexValue 的引用。

所以,如果你做这样的事情 System.out.println(String.class.getClassLoader()) 你会得到 null 因为这个类被 BootStrap ClassLoader 调用,另一方面,如果你对一个类做同样的事情Ext 或 App Class 路径,您将分别获得 $ExtClassLoader@someHexValue 和 sun.misc.Launcher$AppClassLoader@someHexValue 。

如果此类由引导类加载器加载,则此方法将在此类实现中返回 null。

https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getClassLoader()

有一点是肯定的,与从命令行运行相比,Eclipse 具有更深入、更复杂的类加载器设置。 如果您看到一个类的类加载器在一个和另一个中的显示方式不同,那么这很可能是一个原因。

我不知道 Eclipse 到底在做什么,但我认为您的类很可能在从 Eclipse 运行时没有被引导类加载器加载,但是 Eclipse 试图让它看起来像那样。

一旦应用程序被引导,引导类加载器就是静态的,除非 Eclipse 覆盖了实现,否则以后不能向它添加 jars 或类......在这种情况下,还有另一种可能的解释。

有类似的问题。 通过不使用 getClass 方法解决。 以下为我工作。

<ClassName>.class.getClassLoader();

@dilou 的回答指出了正确的方向。 检查Eclipse中运行配置的设置:Go到Classpath选项卡并检查添加依赖项的位置。 有两类:

  • 引导条目
  • 用户条目

如果将依赖项添加到第一个类别,则会使用引导classloader ,并且大多数其他答案中提到的问题都会发生:它返回为 null。

因此,要解决该问题,请将您的依赖项移至“用户条目”部分。

我有同样的问题。 但是使用以下方法解决了它:-

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

希望这可以帮助其他人...

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

出于安全目的,空类加载器是为系统类保留的,并且只能在 Class.forName(String name, boolean initialize, ClassLoader loader) 时使用。 如果一个类的 ClassLoader 为空,则不会进行大多数安全检查。

在启动应用程序时,为了了解 Eclipse 在类路径设置方面究竟做了什么,单击应用程序类路径设置下的“显示命令行”按钮可能会有所帮助。 (我正在使用 Eclipse 2020-06)。 对我来说,它显示了包含调用<ClassName>.class.getClassLoader();类的 jar 文件<ClassName>.class.getClassLoader(); 返回null,实际上前面是
-Xbootclasspath/a:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM