Java 修飾符分為兩大類:
| 修飾符 | 同類 | 同包 | 子類(異包) | 非子類(異包) |
|---|---|---|---|---|
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ | ✗ |
default (包私有) | ✓ | ✓ | ✗ | ✗ |
private | ✓ | ✗ | ✗ | ✗ |
// mypackage/Person.java
package mypackage;
class Person { // default 類,僅包內可見
private String name; // 僅本類可見
protected void setName(String name) { this.name = name; } // 包內+子類可見
public String getName() { return name; } // 任意處可見
}
// mypackage/Company.java
package mypackage;
public class Company { // public 類,任意處可見
private List<Person> people = new ArrayList<>(); // 僅本類可見
public void addPerson(String name) {
Person p = new Person();
p.setName(name); // 同包訪問 protected 方法 ✓
people.add(p);
}
}
// MainDriver.java (無包 / 異包)
import mypackage.*;
public class MainDriver {
public static void main(String[] args) {
Company c = new Company(); // public 類 ✓
c.addPerson("Nic"); // public 方法 ✓
Person p = new Person(); // 編譯錯誤:Person 是 default 類,異包不可見
p.setName("Maria"); // 編譯錯誤:protected 方法,異包非子類不可見
}
}
new 即可調用this/super
// 經典用法
int max = Integer.MAX_VALUE; // 靜態常量
int num = Integer.parseInt("1234"); // 靜態工具方法
| 修飾目標 | 效果 |
|---|---|
| 類 | 不可被繼承(如 String、Integer) |
| 方法 | 不可被重寫(但可重載) |
| 變量(基本類型) | 值不可修改(編譯期常量) |
| 變量(引用類型) | 引用不可修改,但對象內部狀態可變 |
abstract class Shape {
abstract double area(); // 強制子類實現
}
class Circle extends Shape {
private double r;
@Override double area() { return Math.PI * r * r; }
}
this,靜態方法鎖 Class 對象
// 同步方法
public synchronized void print(String s) {
for (int i = 0; i < 5; i++)
System.out.println(s + ": " + i);
}
// 同步代碼塊(更精細控制鎖範圍)
public void print(String s) {
synchronized (this) { // 或自定義鎖對象
for (int i = 0; i < 5; i++)
System.out.println(s + ": " + i);
}
}
volatile int i; i++ 仍非線程安全)
public class ThreadExample {
// 狀態標誌,volatile 確保線程間可見
public static volatile boolean isActive = true;
public static void main(String[] args) {
new Thread(() -> {
while (true) if (isActive) { System.out.println("T1"); isActive = false; }
}).start();
new Thread(() -> {
while (true) if (!isActive) { System.out.println("T2"); isActive = true; }
}).start();
}
}
無 volatile 時,線程可能緩存舊值導致只交替一次;加上後正常交替打印。
abstract 不能與 final、private、static 共存interface 中方法隱含 public abstract,字段隱含 public static finalenum 隱含 final,不可繼承final(Java 8+ 可省略)修飾符是 Java 封裝、繼承、多態、並發的基石。建議:
private > default > protected > public)static final,工具方法用 staticsynchronized/Lock,單純狀態標誌用 volatileabstract/final 控制擴展性