Java9中,Synthetic和Mandated Modifier有什么区别?

17

在Java文档中,ExportsModifier指出:

MANDATED 导出在模块声明源代码中被隐式声明。

SYNTHETIC 导出在模块声明源代码中未被显式或隐式声明。

通过查看一些 module-info.class 文件,我可以看到通常有两种用法:

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;
    ...
}

Qualified Exports描述了这两种类型,但文档中没有提及枚举类型。这些是文档中提到的不同类型吗?

Q1. 通常情况下,SYNTHETICMANDATED都是修饰符,如在ExportsModuleDescriptorOpensRequires中使用。这两者之间有什么区别,实践中是否有一种优于另一种?

Q2. 如果一个Synthetic Modifier不是在模块源代码中声明的,那么它的一个例子是什么?


2
你不是回答这些问题的人吗?;-) - GhostCat
@GhostCat 哈哈..我想我得努力尝试一下。我真的找不到任何简单的参考资料。我将依靠社区回来提供一些/更好的细节 :) - Naman
1
让我们等待Alan回答这个问题,但我猜合成导出可能是为自动模块和未命名模块创建的那些。这样的模块即使没有声明“exports”子句,也会导出包。但我只是在猜测... - Nicolai Parlog
@Nicolai 期待答案。我也考虑过自动模块的问题。但问题是,这与强制性模块有何不同? - Naman
5
JVMS定义了ACC_MANDATED和ACC_SYNTHETIC标志,这些枚举只是在API中反映了这些标志。如果您编译module m { }并使用javap -v检查生成的module-info.class,则会看到requires java.base设置了ACC_MANDATED标志。较难找到设置了ACC_SYNTHETIC的模块示例,但代理类被封装时是一个例子。在这种情况下,生成的动态模块具有设置了ACC_SYNTHETIC标志。 - Alan Bateman
显示剩余2条评论
1个回答

2
合成和指定修饰符的区别很简单——指定修饰符是隐式声明的,而合成修饰符既没有隐式声明也没有显式声明。关于这个问题有很好的文章,Java规范对早期引入到Java中的合成修饰符也有详细的说明。以下关于合成修饰符的详细信息是从那些文章中提取出来的,因为它们包含了完整的细节。请在末尾找到参考资料。
合成:

The Synthetic attribute is a fixed-length attribute in the attributes table of a ClassFile, field_info, or method_info structure (§4.1, §4.5, §4.6). A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. The only exceptions to this requirement are compiler-generated methods which are not considered implementation artifacts, namely the instance initialization method representing a default constructor of the Java programming language (§2.9), the class initialization method (§2.9), and the Enum.values() and Enum.valueOf() methods. Java synthetic classes, methods and fields are for java runtime’s internal purposes. We may not need to have knowledge about them to write the code.

The Synthetic attribute was introduced in JDK release 1.1 to support nested classes and interfaces.

The Synthetic attribute has the following format:

Synthetic_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
}

The items of the Synthetic_attribute structure are as follows:

attribute_name_index The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure representing the string "Synthetic".

attribute_length The value of the attribute_length item is zero. Uses of Java Synthetic • It might be useful in debugging sessions, when we see those synthetic stuff in stack trace we can understand what it is. • AOP, generics, enums uses Java synthetic. • Java reflection API exposes method to check if an element is synthetic. • A regular java application programmer will not require synthetic for day to day programming. • This knowledge may be required in interviews but that doesn’t mandate that you will use it in the project. When synthetic is created? When an enclosing class accesses a private attribute of a nested class, Java compiler creates synthetic method for that attribute. If there is a getter method available in source then this synthetic method will not be created. Similarly for constructor of inner classes also synthetic is created. There are many occasions, like this where a synthetic field or method or class is created.

强制执行:

The opens package was implicitly declared in the source of the module declaration. This dependence was declared in the module declaration. A mandated construct is the one that is not explicitly declared in the source code, but whose presence is mandated by the specification. Such a construct is said to be implicitly declared. One example of a mandated element is a default constructor in a class that contains no explicit constructor declarations. Another example of a mandated construct is an implicitly declared container annotation used to hold multiple annotations of a repeatable annotation type. Ex:

 Module claim
 requires mandated java.base

Line 1. Defines the module called claim. In line 2 defines every module depends on java.base module except java.base. That means export was implicitly declared in the source module declaration.

References:


1
嗨!欢迎来到stackoverflow,感谢您为回答问题付出了这么多的努力。小小的请求,您能否提供您所参考的文档链接,并改善答案的格式呢?这将提高其可读性。 - Naman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接