17

java 文档中的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;
    ...
}

合格的导出确实描述了这两种类型,但没有提到枚举类型。这些是文档中提到的不同类型吗?

Q1。通常,SYNTHETICand、和MANDATED中使用的修饰符。这两者之间有什么区别,在实践中一个优于另一个?ExportsModuleDescriptorOpensRequires

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

4

1 回答 1

2

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

合成的:

Synthetic 属性是 ClassFile、field_info 或 method_info 结构(§4.1、§4.5、§4.6)的属性表中的固定长度属性。未出现在源代码中的类成员必须使用 Synthetic 属性进行标记,否则必须设置其 ACC_SYNTHETIC 标志。此要求的唯一例外是编译器生成的方法,它们不被视为实现工件,即表示 Java 编程语言的默认构造函数的实例初始化方法(第 2.9 节)、类初始化方法(第 2.9 节)和枚举。 values() 和 Enum.valueOf() 方法。Java 合成类、方法和字段用于 Java 运行时的内部用途。我们可能不需要了解它们来编写代码。

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

Synthetic 属性具有以下格式:

Synthetic_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
}

Synthetic_attribute结构的项目如下:

attribute_name_index attribute_name_index 项的值必须是对 constant_pool 表的有效索引。该索引处的 constant_pool 条目必须是表示字符串“Synthetic”的 CONSTANT_Utf8_info (§4.4.7) 结构。

attribute_length attribute_length 项的值为零。Java Synthetic 的使用 • 它在调试会话中可能很有用,当我们在堆栈跟踪中看到那些合成的东西时,我们可以理解它是什么。• AOP、泛型、枚举使用Java 合成。• Java 反射API 公开了检查元素是否是合成的方法。• 普通的Java 应用程序程序员将不需要合成来进行日常编程。• 面试中可能需要这些知识,但这并不要求您在项目中使用它。什么时候合成的?当封闭类访问嵌套类的私有属性时,Java 编译器会为该属性创建合成方法。如果源中有可用的 getter 方法,则不会创建此合成方法。同样,对于内部类的构造函数,也会创建合成的。有很多场合,例如创建合成字段或方法或类的情况。

授权:

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

 Module claim
 requires mandated java.base

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

参考:

于 2017-10-03T09:15:23.230 回答