public / private / protected / static / final
| Since: | Java 1.0(1996) |
|---|
Modifiers that control access to classes, fields, and methods. Use public, private, and protected to specify accessibility, static to define members that belong to the class rather than an instance, and final to declare constants that cannot be changed.
Syntax
// Field definitions with access modifiers.
public String name;
private int age;
protected double score;
// Static field (class variable) definition.
static int count = 0;
// Constant definition (combining static and final).
static final double PI = 3.14159;
// Static method definition.
static void printCount() {
System.out.println(count);
}
// Accessor methods (getter / setter) for a private field.
public int getAge() { return age; }
public void setAge(int age) {
if (age >= 0) this.age = age;
}
Modifier List
| Modifier | Description |
|---|---|
| public | Accessible from any class. |
| private | Accessible only within the same class. Fields are typically declared private for encapsulation. |
| protected | Accessible within the same package and from subclasses. |
| (none) | Package-private. Accessible only from classes in the same package. |
| static | A member that belongs to the class, not an instance. Can be accessed without creating an instance. |
| final (field) | A constant that cannot be changed once assigned. Use static final to define a class-level constant. |
| final (class) | Defines a class that cannot be extended (e.g., the String class). |
| final (method) | Defines a method that cannot be overridden in a subclass. |
Sample Code
AccessModifiers.java
class Counter {
// Private field (not directly accessible from outside)
private int count = 0;
// Static field (shared across all instances)
static int total = 0;
// Constant (cannot be changed)
static final int MAX = 100;
// A public method manipulates the private field (encapsulation).
public void increment() {
if (count < MAX) {
count++;
total++;
}
}
public int getCount() { return count; }
}
class MathHelper {
static int square(int n) { return n * n; }
}
class AccessModifiers {
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.increment();
c1.increment();
c2.increment();
System.out.println(c1.getCount()); // Prints "2".
System.out.println(c2.getCount()); // Prints "1".
System.out.println(Counter.total); // Prints "3" (shared via static).
System.out.println(Counter.MAX); // Prints "100".
// Static methods are called using the class name.
System.out.println(MathHelper.square(5)); // Prints "25".
}
}
The command looks like this:
javac AccessModifiers.java java AccessModifiers 2 1 3 100 25
Common Mistakes
Common Mistake 1: Directly accessing a private field from outside the class causes a compile error
A private field cannot be accessed directly from outside its class. To read or write the value from outside, you must use getter and setter methods.
AccessNg.java
class Fighter {
private String name = "Yagami Iori";
private int power = 95;
}
class AccessNg {
public static void main(String[] args) {
Fighter f = new Fighter();
System.out.println(f.name);
f.power = 100;
}
}
The command looks like this:
javac AccessNg.java
java AccessNg
AccessNg.java:10: error: name has private access in Fighter
System.out.println(f.name);
^
AccessNg.java:11: error: power has private access in Fighter
f.power = 100;
^
2 errors
Access private fields through getter and setter methods defined within the same class.
AccessOk.java
class Fighter {
private String name = "Yagami Iori";
private int power = 95;
public String getName() { return name; }
public int getPower() { return power; }
public void setPower(int power) {
if (power >= 0) this.power = power;
}
}
class AccessOk {
public static void main(String[] args) {
Fighter f = new Fighter();
System.out.println(f.getName());
f.setPower(100);
System.out.println(f.getPower());
}
}
The command looks like this:
javac AccessOk.java java AccessOk Yagami Iori 100
Common Mistake 2: Confusing a static field with an instance variable
A static field has exactly one copy shared by all instances. If you want each instance to hold its own value, do not declare the field static.
StaticNg.java
class Player {
static int score = 0;
public void addScore(int points) {
score += points;
}
}
class StaticNg {
public static void main(String[] args) {
Player iori = new Player();
Player kyo = new Player();
iori.addScore(50);
kyo.addScore(30);
System.out.println(iori.score);
System.out.println(kyo.score);
}
}
The command looks like this:
javac StaticNg.java java StaticNg 80 80
To give each instance its own value, declare the field without static so it becomes an instance field.
StaticOk.java
class Player {
int score = 0;
public void addScore(int points) {
score += points;
}
}
class StaticOk {
public static void main(String[] args) {
Player iori = new Player();
Player kyo = new Player();
iori.addScore(50);
kyo.addScore(30);
System.out.println(iori.score);
System.out.println(kyo.score);
}
}
The command looks like this:
javac StaticOk.java java StaticOk 50 30
Notes
As a principle of encapsulation, it is common practice to declare fields private and access them through getters and setters. This allows you to centralize validation logic for field values.
static members belong to the class and can be used without creating an instance; their values are shared across all instances. They are commonly used for counters, constants, and utility methods. By convention, constants are named in UPPER_SNAKE_CASE.
For class definitions and instance creation, see class / new / Constructor / this. For inheritance, see extends / super / @Override.
If you find any errors or copyright issues, please contact us.