![](/img/trans.png)
[英]this.getClass().getClassLoader().getResourceAsStream always returning 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.