Modifiers are keywords that you add to definitions to change their meanings. Java has a wide variety of modifiers, which are divided into two groups:
Access modifiers are used to set the accessibility of classes, interfaces, variables, methods, constructors, and data members.
public: The class is accessible by any other class.default: The class is only accessible by classes in the same package. This is used when you don't specify a modifier.public: The code is accessible for all classes.private: The code is only accessible within the declared class.protected: The code is accessible in the same package and subclasses.default: The code is only accessible in the same package.The table below illustrates the visibility:
| Modifier | Same Class | Same Package | Subclass | World |
|---|---|---|---|---|
public |
Y | Y | Y | Y |
protected |
Y | Y | Y | N |
default |
Y | Y | N | N |
private |
Y | N | N | N |
public class MyClass {
public String publicVar = "I am public!";
private String privateVar = "I am private!";
public void display() {
// The private variable is accessible inside the class
System.out.println(privateVar);
}
}
// In another class...
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
System.out.println(obj.publicVar); // This works
// System.out.println(obj.privateVar); // This would cause an error
obj.display(); // This works and prints the private variable
}
}
Non-access modifiers are used to provide information about the characteristics of a class, method, or variable to the JVM.
final: The class cannot be inherited by other classes.abstract: The class cannot be used to create objects. To access an abstract class, it must be inherited from another class.final: Attributes and methods cannot be overridden or modified.static: Attributes and methods belong to the class, rather than an object.abstract: Can only be used in an abstract class, and can only be used on methods. The method does not have a body, e.g. abstract void run();. The body is provided by the subclass.transient: Attributes and methods are skipped when serializing the object containing them.synchronized: Methods can only be accessed by one thread at a time.volatile: The value of an attribute is not cached thread-locally, and is always read from the "main memory".
public class Main {
final double PI = 3.14; // A final variable (constant)
static int instanceCount = 0; // A static variable
public Main() {
instanceCount++; // Increment the static counter for each new object
}
public static void main(String[] args) {
Main obj1 = new Main();
Main obj2 = new Main();
System.out.println("Instances created: " + Main.instanceCount); // Access static var on the class
}
}