Java Modifiers
- Summary
-
Discussion
- Could you explain Java's access modifiers?
- Could you explain Java's static modifier?
- Which modifiers affect inheritance in Java?
- Could you explain the abstract method modifier?
- Could you explain transient and volatile field modifiers?
- Could you explain native and synchronized method modifiers?
- Could you explain the Modifier class?
- Milestones
- References
- Further Reading
- Article Stats
- Cite As
A modifier is a programming construct in Java used to modify/refine/restrict a declaration. With modifiers, developers can restrict access, limit class instantiation to a single instance, disallow value modification, control persistent storage, configure sharing of variables across threads, and more. Modifiers can be applied to classes, class fields, class methods, class constructors and interfaces.
Most modifiers are keywords, meaning that developers can't use them as identifiers. Modifiers sealed and non-sealed are not keywords.
In some cases, default modifiers are applied when modifiers are not explicitly specified by the developer. However, it's a good practice to explicitly specify modifiers.
Annotations are considered as modifiers but these are not covered in this article.
Discussion
-
Could you explain Java's access modifiers? Access to a class, interface, field, method or constructor can be controlled via access modifiers. Any one of these three can be used:
public: access to everyoneprotected: access to subclasses anywhere plus everyone within the packageprivate: access limited to the class
When no access modifier is specified, by default access is restricted to within the package; that is, anyone within the package can access. This is also called package-private. The Java Language Specification (section 6.6) gives more details.
Broadly, there are two levels of access control: (a) top level: public or package-private; (b) member level: public, protected, package-private, private. Top level applies to classes and interfaces. Member level applies to members of classes and interfaces, including nested classes and interfaces.
As a best practice, members should be private unless there's a need to expose them. This hides the internal implementation. Except for constants, avoid public fields. Access to top level public classes and interfaces can be restricted to the module by not exporting them.
-
Could you explain Java's staticmodifier?
There are use cases where we wish that all instances of a class share fields rather than have separate copies. Logging is an example where multiple instances log via the same logger. Another example is the method
public static main(String[] args)that forms the entry point for any program. The JVM starts execution from this method even when no instance has been created. Thestaticmodifier enables us to do this.Nested classes can be static. Local or anonymous classes can't be static. Nested enum classes and nested record classes are implicitly static.
A static field/method is also called a class variable/method. In a static context, the use of
thisandsuperare not allowed. Static fields can be initialized using field initializers or static initializers that may include one or more blocks of code.A nested interface, member or local, is implicitly static.
Static fields/methods are preferably accessed via the class name. Static methods can't be overridden since they're resolved at compile time. Static methods can't be abstract.
-
Which modifiers affect inheritance in Java? A subclass or subinterface can extend or implement from another class or one or more interfaces. This is one way by which Java enables code reuse. However, modifiers
final,sealedandnon-sealedhelp developers control inheritance. These modifiers may be used towards a more maintainable code. For example, aVehicleclass may state that onlyCarandTrucksubclasses can extend it. This avoids the inelegant use ofinstanceoforif-elsestatements. Thus, runtime checks are replaced with compile-time checks.A class is declared
finalwhen it's desired that no subclass can extend it. It's methods can't be overridden. A final class can't be abstract.A class/interface is declared
sealedif it specifies all known subclasses/subinterfaces. The subclasses/subinterfaces themselves may besealed; ornon-sealedif they can be freely extended. A permitted subclass must be itself be declared asfinal,sealedornon-sealed. -
Could you explain the abstractmethod modifier?Sometimes we wish to share code among closely related classes. But what's common among these classes is incomplete in the sense that their superclass can't be instantiated. An example is the
area()method of classShape. SubclassesCircleandRectanglecan and should implement this method butShapeitself is too abstract to implement it.The
abstractmodifier is applicable to classes, methods and interfaces. However, since every interface is implicitly abstract (since classes are expected to implement an interface), explicit use of this modifier for interfaces is obsolete.A class with at least one abstract method must itself be declared abstract. A class that partially implements an interface must be declared abstract. A subclass of an abstract class itself can be abstract. In all cases, abstract classes can be subclassed but can't be instantiated. An abstract class can be
sealedbut not madefinal. -
Could you explain transientandvolatilefield modifiers?Sometimes there's a need to store an object in a persistent manner, such as into a database or a disk file. Java's
java.io.Serializableclass helps us to serialize the object for storage. But what if there are some fields that we don't wish to save? This is where thetransientmodifier can be used. Fields with this modifier are ignored for storage.Java allows multiple threads to share variables. Using locks, developers can enforce mutual exclusion on those shared variables. However, the use of
volatilemodifier gives developers an alternative approach. The Java Memory Model ensures that all threads see a consistent value without extra effort from developers. Afinalvariable can't also be declaredvolatile. -
Could you explain nativeandsynchronizedmethod modifiers?Sometimes we wish to reuse functionality already implemented in another language. This may be legacy code, platform-dependent code or code written for better performance or low-level hardware access. The
nativemodifier tells the Java compiler that the method is implemented elsewhere. No method body is supplied. Instead the method declaration ends with a semicolon. Native code is interfaced to the JVM via Java Native Interface (JNI).The
synchronizedmodifier helps developers write methods that can run concurrently in a multi-threaded environment. For example, suppose one method puts items into a queue or updates a variable, and another method executing in a concurrent thread reads from the queue or variable. With the use ofsynchronizedmodifier, method executions will not get pre-empted.Under the hood, a synchronized method acquires a monitor. For a class method, the monitor is associated with the class. For an instance method, it's associated with
this. -
Could you explain the Modifierclass?Java's
Modifierclass is part of thejava.lang.reflectpackage. Reflection allows a program to get information about classes at runtime. Via static methods and constants, theModifierclass gives information about class and method access modifiers. Examples of constants areABSTRACT,FINALandSTATIC. Examples of methods areisAbstract(int),isFinal(int),isStatic(int),classModifiers()andmethodModifiers().An example usage would be to call the
getModifiers()methods on an instance ofjava.lang.Class,java.lang.reflect.Field,java.lang.reflect.Methodorjava.lang.reflect.Constructor. The returned value can be processed using thejava.lang.reflect.Modifierclass.
Milestones
1996
Java 1.0 is released. This release includes access modifiers public, protected and private; class modifiers abstract and final; field modifiers static, final, transient and volatile; method modifiers abstract, static, final, native and synchronized; and interface modifier abstract. The use of abstract modifier for interfaces is redundant since interfaces are abstract by definition.
1998
Java 1.2 is released. This adds the modifier strictfp to enforce strict floating-point semantics regardless of the platform. In Java SE 17 (September 2021), this modifier is made obsolete since by then processors support SSE2 (Streaming SIMD Extensions 2) that natively supports strict floating-point semantics.
2017
Java SE 9 is released. For better modularity, the module concept is introduced. A module's packages are accessible to other modules only if the module exports them and modules that use them explicitly require them. This refines the semantics of the top level public access modifier and nested public and protected modifiers. Moreover, runtime-only access to packages can be achieved via opens and open directives.
2020
References
- Baeldung. 2017. "A Guide to the Static Keyword in Java." Baeldung, October 27. Updated 2021-11-24. Accessed 2022-05-03.
- Baeldung. 2018. "Guide to JNI (Java Native Interface)." Baeldung, May 27. Updated 2021-12-31. Accessed 2022-05-04.
- Baeldung. 2019. "The Java Native Keyword and Methods." Baeldung, January 1. Updated 2019-10-09. Accessed 2022-05-04.
- Deitel, Paul. 2017. "Understanding Java 9 Modules." Excerpt from Java Magazine, September/October. Accessed 2022-05-03.
- French, Tim. 2013. "Java Primer." CITS2200: Data Structures and Algorithms, The University of Western Australia. Accessed 2022-05-03.
- Gosling, James, Bill Joy, and Guy Steele. 1996. "The Java™ Language Specification." Addison-Wesley. Accessed 2022-05-03.
- Gosling, James, Bill Joy, Guy Steele, Gilad Bracha, Alex Buckley, Daniel Smith, and Gavin Bierman. 2022. "The Java® Language Specification." Java SE 18 Edition, Oracle America, Inc., February 23. Accessed 2022-05-01.
- Krill, Paul. 2021. "JDK 17: The new features in Java 17." InfoWorld, September 14. Accessed 2022-05-03.
- Minh, Nam Ha. 2022. "Java SE versions history." CodeJava. Accessed 2022-05-03.
- OWASP. 2022. "Poor Logging Practice." OWASP. Accessed 2022-05-03.
- Oracle. 2020. "3. Sealed Classes." Java Language Updates, Java SE 15, Oracle, September 14. Accessed 2022-05-03.
- Oracle. 2022a. "Java Language Keywords." The Java™ Tutorials, Oracle. Accessed 2022-05-02.
- Oracle. 2022b. "Examining Class Modifiers and Types." The Java™ Tutorials, Oracle. Accessed 2022-05-02.
- Oracle. 2022c. "Retrieving and Parsing Field Modifiers." The Java™ Tutorials, Oracle. Accessed 2022-05-02.
- Oracle. 2022d. "Retrieving and Parsing Method Modifiers." The Java™ Tutorials, Oracle. Accessed 2022-05-02.
- Oracle. 2022e. "Retrieving and Parsing Constructor Modifiers." The Java™ Tutorials, Oracle. Accessed 2022-05-02.
- Oracle. 2022f. "Controlling Access to Members of a Class." The Java™ Tutorials, Oracle. Accessed 2022-05-03.
- Oracle. 2022g. "Lesson: A Closer Look at the "Hello World!" Application." The Java™ Tutorials, Oracle. Accessed 2022-05-03.
- Oracle. 2022h. "Abstract Methods and Classes." The Java™ Tutorials, Oracle. Accessed 2022-05-03.
- Oracle. 2022i. "Class Modifier." Documentation, Java SE 18, Oracle. Accessed 2022-05-02.
- Oracle. 2022j. "Package java.lang.reflect." Documentation, Java SE 18, Oracle. Accessed 2022-05-04.
- Programming Guide. 2022. "Java: Abstract interfaces and abstract interface methods." Programming Guide. Accessed 2022-05-03.
- Strmecki, Daniel. 2021. "Sealed Classes and Interfaces in Java 15." Baeldung, July 8. Accessed 2022-05-03.
Further Reading
- Oracle. 2022f. "Controlling Access to Members of a Class." The Java™ Tutorials, Oracle. Accessed 2022-05-03.
- Baeldung. 2017. "A Guide to the Static Keyword in Java." Baeldung, October 27. Updated 2021-11-24. Accessed 2022-05-03.
- Oracle. 2020. "3. Sealed Classes." Java Language Updates, Java SE 15, Oracle, September 14. Accessed 2022-05-03.
- Oracle. 2022h. "Abstract Methods and Classes." The Java™ Tutorials, Oracle. Accessed 2022-05-03.
Article Stats
Cite As
See Also
- Java Annotation
- Java (Language)
- Java Interfaces
- Composition vs Inheritance
- SOLID Design Principles
- Design Patterns