Java Modularity Part 5 – Reflection

Java modularity

One of the key design drivers of Java modularity was strong encapsulation. By default, a type in a module is not accessible to other modules unless it’s a public type and its containing package is exported. We can choose exactly which packages we want to expose; the rest are hidden.

(For the rest of this post, when we refer to a type, that term includes classes, interfaces, enums and annotations.)

Before Java 9, we could use the Reflection API to find the types contained in a package and all the members of a type, even the private members. Any code can access any types, so nothing was properly encapsulated.

From Java 9, modular encapsulation also applies to reflection.

If you missed the previous posts in this sequence, you can find them here:

Java Modularity: Reflection Control Levels

There are three levels of runtime-only access control that can be applied to reflection in modules:

  • Access to a single package in a module.
  • Access to a single package by specific listed modules.
  • Access to all packages in a module.

Access to a single package in a module

We use the opens module directive to allow a specific package’s public types to be accessible to code in other modules.

All the types in the specified package, their nested public and protected types, and all of the members of all those types are accessible via reflection. This reflection access is at runtime only.


module com.incusdata {
   opens com.incusdata.lib;

Access to a single package by specific listed modules

We use the opens ... to module directive to allow a package’s public types to be accessible to code in specific modules only. This works the same way as the previous open directive, except the reflection access is only to the listed modules. We supply a list of modules separated by commas after the to directive:

module com.incusdata {
   opens com.incusdata.lib to com.acme.service,;

Access to all packages in a module

We may want all the packages in a given module to be accessible at runtime via reflection to all other modules. In this case, we open the whole module by using the open directive in front of the module declaration, as follows:

open module com.incusdata {
   // normal module directives

This is called an open module, and it allows reflective access to all types in all its packages.

Java Modularity: Reflection Defaults

By default, a module with runtime reflective access to a package can see the package’s public types (and their nested public and protected types). However, the code in other modules can access all types in the exposed package and all members within those types, including private members via setAccessible(), as in earlier Java versions.

Code inside a module can use reflection to access all types, and all their members, in all packages in the same module.

What’s Next?

In the next post, we’ll look at the unnamed module and automatic modules. The unnamed module is a similar concept to the default package.

I’m always interested in your opinion, so please leave a comment. Your feedback helps me write tips that help you.

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.