在下面的场景中,我有一个关于保证(如果有的话)的问题(请注意,问题不是“如何以不同的方式完成此操作?”),在下面的情况下,问题实际上是关于类加载顺序的(以更好地理解类加载是如何工作的)。
假设的情况是..。有一个.war文件具有以下(部分)目录结构:
WEB-INF/classes/com/acme/Bunny.class
.
.
.
WEB-INF/lib/acme.jar两个Bunny.class文件都从acme.jar导入引用其他类。
网络中的Bunny.class -INF/classes/.是唯一具有与来自acme.jar的类相同的名称/路径的类。
.jar文件acme.jar还包含com.acme.Bunny (并且没有使用特殊的类加载器技巧)。
我理解Java规范保证了在程序实际使用类(或“手动加载类”)之前不会加载类,这就是为什么如果您填充数千个.jar (例如,在.war中),类加载器不会开始加载成千上万个类。
(编辑)
但是,上面示例中的两个类加载的顺序如何呢?
措辞应该是:
但是如何确定上面两个类中的哪一个是加载的呢?
或类似的事情:)
有一个保证: com.acme.Bunny将在com.acme的任何其他类之前使用.
基本上,在维基百科上,下面是这样写的:
最复杂的JAR地狱问题是在充分利用类加载系统复杂性的情况下出现的。Java程序不需要只使用单一的“平面”类加载程序,而是可以由几个(实际上是数量不定的)嵌套的协作类加载器组成。由不同的类加载器加载的类可能以复杂的方式交互,而开发人员并不完全理解它们,从而导致无法解释的错误或错误。
因此,我想知道:我是否可以确定/classes/com/acme/Bunny.class将在WEB/lib/ dir中的.jar类之前加载?
发布于 2010-12-17 00:18:52
此答案不正确,但不能删除,因为它是已接受的答案。见下面@Sajeev的答案。
发布于 2016-03-30 06:20:34
选择的答案是错误的。Servlet规范版本2.4和3.0明确规定,首先加载WEB/类,然后加载WEB/lib
Servlet 2.4:4-fr-spec.pdf - SRV.9.5节,最后一段
Servlet3.0:0-final-spec.pdf -第10.5节,最后一段
Web应用程序类加载器必须先从WEB/ class目录加载类,然后从WEB/lib目录中的库JAR加载类。
发布于 2010-12-17 00:47:15
WEB-INF/lib/*.jar文件和WEB-INF/classes目录都位于同一个ClassLoader中。这就好像您使用ClassPath中列出的所有jars启动了一个应用程序一样。由于需要解析类名,ClassLoader将从其资源中找到匹配的第一个类。它搜索的确切顺序是不确定的--它取决于平台。
Java包的设计是为了解决名称冲突的问题,如您所描述的。故意将类命名为与其自己的jar文件中绑定的类相同的名称从来都不是一个好主意。更好的解决方案是扩展类并在代码中使用新版本。如果您需要更改该类的功能,那么您可能会看到面向Java方面编程的神奇之处。
https://stackoverflow.com/questions/4466526
复制相似问题