问题
What is the difference between module with open keyword before and without it?
For instance:
open module foo {
}
module foo {
}
回答1:
In order to provide reflective access to your module, Java 9 introduced open keyword.
You can create open module by using open keyword in module declaration.
An open module grants reflective access to all of it's packages to other modules.
For example, if you want to use some framework, that heavily relies on reflection, such as Spring, Hibernate etc, you can use this keyword, to enable reflective access for it.
You can enable reflective access for specified packages of your module by using opens statement in package declaration:
module foo {
opens com.example.bar;
}
or using open keyword in module declaration:
open module foo {
}
but keep in mind, that you cannot combine them:
open module foo {
opens com.example.bar;
}
results with compile-time error.
Hope it helps.
回答2:
A bit of a background to the directives in question. The Module System states in the Breaking encapsulation section
It is sometimes necessary to violate the access-control boundaries defined by the module system, and enforced by the compiler and virtual machine, in order to allow one module to access some of the unexported types of another module. This may be desirable in order to, e.g., enable white-box testing of internal types, or to expose unsupported internal APIs to code that has come to depend on them. The
--add-exports
option can be used, at both compile time and run time, to do this.
The command line option is equivalent to for example:-
module java.logging {
exports java.util.logging;
}
The --add-exports
option enables access to the public types of a specified package.
Though thereafter,
It is sometimes necessary to go further and enable access to all non-public elements via the setAccessible method of the core reflection API. The
--add-opens
option can be used, at runtime, to do this.
This command line option is equivalent to for example:-
module jdk.unsupported {
opens sun.misc;
}
An ordinary named module, by contrast, is defined explicitly with a module declaration as:-
module foo { }
and these are known as explicit modules. Explicit modules can use directives on packages as stated above for example to export
/open
packages to provide reflective access to their respective public members and classes.
On the other hand, an OPEN module is a
module that does not declare any open packages but the resulting module is treated as if all packages are open.
Such that it grants access at runtime to types in all of the module's packages as if all packages are exported which means bytecode or reflection can be used to access every package's classes or members in all packages. The reflection APIs with setAccessible
or MethodHandles.privateLookupIn
allow for deep reflection, so in short you can reflect on all members of all classes in all packages. Which also pretty much explains the reason why compiler won't allow both open directives to a package while the module is already open.
来源:https://stackoverflow.com/questions/46482364/what-is-an-open-module-in-java-9-and-how-to-use-it