有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

为什么Java9不简单地将类路径上的所有JAR转换为自动模块?

为了了解我们的分类:

  • 平台显式模块
  • 应用程序显式模块
  • 开放式模块
  • 自动模块
  • 未命名模块

类路径中的所有类和JAR都将是未命名模块的一部分。但为什么这就是我们需要的?与自动模块相比,它的优势在哪里?我可以“要求”那些该死的旧罐子把它们做成一个自动模块。我不是把所有的东西都包括进去了吗


共 (2) 个答案

  1. # 1 楼答案

    除了公认答案中列出的项目外,还有一个区别:未命名的模块可以访问Java附带的所有模块包,即使它们没有导出。 只要该类是公共的,访问就可以工作——与Java 9之前一样。但一旦从模块路径运行jar,它将只能访问导出的包

    例如,如果某个.jar有以下代码:

    com.sun.jmx.remote.internal.ArrayQueue c = new com.sun.jmx.remote.internal.ArrayQueue(10);
    

    当放置在类路径上时,它将正常运行,没有任何警告,但当从模块路径(作为自动模块)运行时,它将在运行时失败:

    Exception in thread "main" java.lang.IllegalAccessError: class test1.C 
    (in module test1) cannot access class com.sun.jmx.remote.internal.ArrayQueue 
    (in module java.management) because module java.management does not export 
    com.sun.jmx.remote.internal to module test1
    

    请注意,这与众所周知的非法反射访问警告不同,后者是关于使用反射访问私有字段或方法。这里我们静态(非反射)访问公共类(但从非导出包)

  2. # 2 楼答案

    至少有两个原因:

    • 与常规模块一样,自动模块也会受到模块系统的某些检查的怀疑,例如not splitting packages。由于类路径上的JAR可以(偶尔也会)拆分包,因此对它们进行检查将是向后不兼容的,并且会破坏许多应用程序
    • 未命名的模块可以读取所有平台模块,而自动模块只能读取进入模块图的模块。这意味着一个罐子需要java。桌面模块(例如)将从类路径工作,但不会从模块图工作,除非java。桌面也会将其放入图形中(通过依赖项或^{

    我现在没有时间检查第二个,但这就是the State of the Module system所说的:

    After a module graph is resolved, therefore, an automatic module is made to read every other named module, whether automatic or explicit

    解析对已声明的依赖项有效,而自动模块则不声明任何依赖项