# Java Modifiers

## Summary


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 everyone
    + `protected`: access to subclasses anywhere plus everyone within the package
    + `private`: access limited to the classWhen 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 static modifier?

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. The `static` modifier 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 `this` and `super` are 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`, `sealed` and `non-sealed` help developers control inheritance. These modifiers may be used towards a more maintainable code. For example, a `Vehicle` class may state that only `Car` and `Truck` subclasses can extend it. This avoids the inelegant use of `instanceof` or `if-else` statements. Thus, runtime checks are replaced with compile-time checks.

A class is declared `final` when 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 `sealed` if it specifies all known subclasses/subinterfaces. The subclasses/subinterfaces themselves may be `sealed`; or `non-sealed` if they can be freely extended. A permitted subclass must be itself be declared as `final`, `sealed` or `non-sealed`. 


### Could you explain the abstract method 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 class `Shape`. Subclasses `Circle` and `Rectangle` can and should implement this method but `Shape` itself is too abstract to implement it. 

The `abstract` modifier 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 `sealed` but not made `final`.  


### Could you explain transient and volatile field 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.Serializable` class 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 the `transient` modifier 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 `volatile` modifier gives developers an alternative approach. The Java Memory Model ensures that all threads see a consistent value without extra effort from developers. A `final` variable can't also be declared `volatile`. 


### Could you explain native and synchronized method 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 `native` modifier 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 `synchronized` modifier 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 of `synchronized` modifier, 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 Modifier class?

Java's `Modifier` class is part of the `java.lang.reflect` package. Reflection allows a program to get information about classes at runtime. Via static methods and constants, the `Modifier` class gives information about class and method access modifiers. Examples of constants are `ABSTRACT`, `FINAL` and `STATIC`. Examples of methods are `isAbstract(int)`, `isFinal(int)`, `isStatic(int)`, `classModifiers()` and `methodModifiers()`. 

An example usage would be to call the `getModifiers()` methods on an instance of `java.lang.Class`, `java.lang.reflect.Field`, `java.lang.reflect.Method` or `java.lang.reflect.Constructor`. The returned value can be processed using the `java.lang.reflect.Modifier` class.

## Milestones

Jan  
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. 

Dec  
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. 

Sep  
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. 

Sep  
2020

Java SE 15 is released. This adds modifiers `sealed` and `non-sealed` to give developers control on inheritance hierarchy. Classes and interfaces can be controlled with these modifiers. The `permits` clause specifies which classes and interfaces can extend or implement the current class or interface.