Java9中的Synthetic和Mandated Modifier有什么区别

Nam*_*man 15 java java-9 java-module module-info

java doc中的ModifierforExports表明了这一点

MANDATED 导出在模块声明的源中隐式声明.

SYNTHETIC 未在模块声明的源中显式或隐式声明导出.

看几个module-info.classes,我可以看到通常有两种类型的用法:

module java.base {
    ...
    exports java.util; // type 1
    exports java.util.concurrent;
    exports java.util.concurrent.atomic;
    exports jdk.internal to jdk.jfr; // type 2
    exports jdk.internal.jmod to
        jdk.compiler,
        jdk.jlink;
    ...
}
Run Code Online (Sandbox Code Playgroud)

合格的出口做介绍这两种,但没有对枚举类型没有提及.这些是文档中提到的不同类型吗?

Q1.一般来说SYNTHETICMANDATED作为在使用调节剂Exports,ModuleDescriptor,OpensRequires.这两者之间的区别是什么,在实践中优于另一个?

Q2.Synthetic Modifier如果没有在模块的源代码中声明,那么无论如何都是一个例子?

小智 2

Synthetic 和 Mandated 修饰符的区别很简单——mandated 是隐式声明的,而 Synthetic 不是隐式或显式声明的。有关于这方面的好文章,并且 java 规范对早期引入 java 的合成修饰符有详细的解释。由于细节的完整性,以下与合成相关的细节是从这些细节中提取的。请在最后找到参考资料。

\n\n

合成的:

\n\n
\n

综合属性是 ClassFile、field_info 或 method_info 结构的 attribute\n 表中的固定长度属性(\xc2\xa74.1、\n \xc2\xa74.5、\xc2\xa74.6)。未出现在源代码中的类成员必须使用 Synthetic 属性进行标记,否则必须设置其 ACC_SYNTHETIC 标志。此要求的唯一例外是编译器生成的方法,它们不被视为实现工件,即表示 Java 编程语言 (\xc2\xa72.9) 的默认构造函数的实例初始化方法、类\ n 初始化方法 (\xc2\xa72.9),以及 Enum.values() 和 Enum.valueOf()\n 方法。Java 合成类、方法和字段用于 java\n runtime\xe2\x80\x99s 内部用途。我们可能不需要了解它们来编写代码。

\n\n

Synthetic 属性是在 JDK 版本 1.1 中引入的,用于支持嵌套类和接口。

\n\n

综合属性具有以下格式:

\n\n
Synthetic_attribute {\n    u2 attribute_name_index;\n    u4 attribute_length;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

Synthetic_attribute结构体的各项如下:

\n\n

attribute_name_index attribute_name_index 项的值必须是constant_pool 表的有效索引。该索引处的constant_pool 条目必须是表示字符串“Synthetic”的CONSTANT_Utf8_info (\xc2\xa74.4.7) 结构。

\n\n

attribute_length attribute_length 项的值为零。Java 合成 \xe2\x80\xa2 的使用\n 它在调试会话中可能很有用,当我们\n 在堆栈跟踪中看到那些合成内容时,我们可以理解它是什么。\n \xe2\x80\xa2 AOP、泛型、 enums 使用 Java 合成。\xe2\x80\xa2 Java 反射 API\n 公开方法来检查元素是否是合成的。\xe2\x80\xa2 常规的 java\n 应用程序程序员不需要合成来进行日常\n 编程。\xe2\x80\xa2 面试中可能需要这些知识,但这并不\xe2\x80\x99 要求您在项目中使用它。合成何时创建?当封闭类访问嵌套类的私有属性时,Java 编译器会为该属性创建合成方法。如果源中有可用的 getter 方法,则不会创建此合成方法。类似地,对于内部类的构造函数,也会创建合成的。在很多情况下,都会创建合成字段、方法或类。

\n
\n\n

规定:

\n\n
\n

opens 包在模块声明的源代码中隐式声明。这种依赖关系是在模块声明中声明的。强制构造是指未在源代码中显式声明的构造,但其存在是由规范强制规定的。这种构造被认为是隐式声明的。强制元素的一个示例是类中不包含显式构造函数声明的默认构造函数。强制构造的另一个示例是隐式声明的容器注释,用于保存可重复注释类型的多个注释。前任:

\n\n
 Module claim\n requires mandated java.base\n
Run Code Online (Sandbox Code Playgroud)\n\n

第 1 行。定义名为 Claim 的模块。第 2 行定义了除 java.base 之外的每个\n 模块都依赖于 java.base 模块。这意味着 export\n 是在源模块声明中隐式声明的。

\n
\n\n

参考:

\n\n\n