static 修飾的成員屬於類級別,類加載時初始化,全類共享單份存儲。非靜態成員屬於實例級別,每個對象獨立一份。
// 非靜態:每個對象獨立存儲
class Box { int l, w, h; }
Box a = new Box(10,20,30);
Box b = new Box(40,20,10);
// 堆中:a.l=10, a.w=20... b.l=40, b.w=20... 互不干擾
// 靜態:所有對象共享同一地址
class StaticDemo { static int m; int n; }
StaticDemo s1 = new StaticDemo();
StaticDemo s2 = new StaticDemo();
s1.m = 100;
System.out.println(s2.m); // 100 (共享)
// 方法區/元空間:StaticDemo.m = 100
public static final(配合 final 內聯優化)。ClassName.field 無需創建對象。// 推薦:類名訪問
StaticDemo.m = 10;
int x = StaticDemo.m;
// 不推薦:對象訪問(編譯器轉為類名,誤導閱讀者)
StaticDemo obj = new StaticDemo();
int y = obj.m; // 警告:static member accessed via instance
this,不能直接訪問非靜態成員(字段/方法)。public final class MathUtils {
private MathUtils() {} // 防實例化
public static int max(int a, int b) {
return a > b ? a : b;
}
public static double sqrt(double x) {
return Math.sqrt(x); // 委託 JDK
}
}
// 調用
int m = MathUtils.max(10, 20); // 無需 new
public class DatabaseConfig {
static final String URL;
static final String USER;
static final String PASS;
static { // 類加載時執行一次
try (InputStream is = DatabaseConfig.class.getResourceAsStream("/db.properties")) {
Properties p = new Properties();
p.load(is);
URL = p.getProperty("url");
USER = p.getProperty("user");
PASS = p.getProperty("pass");
} catch (IOException e) {
throw new ExceptionInInitializerError(e); // 包裝為 Error
}
}
}
Class.forName、首次 new、首次訪問靜態成員)執行一次。ExceptionInInitializerError(受檢異常不可拋出)。// 父類靜態 → 子類靜態 → 父類實例 → 父構造 → 子類實例 → 子構造
class Parent {
static { System.out.println("P-static"); }
{ System.out.println("P-instance"); }
public Parent() { System.out.println("P-ctor"); }
}
class Child extends Parent {
static { System.out.println("C-static"); }
{ System.out.println("C-instance"); }
public Child() { System.out.println("C-ctor"); }
}
public class Test {
public static void main(String[] args) {
new Child();
}
}
/* 輸出:
P-static
C-static
P-instance
P-ctor
C-instance
C-ctor
*/
{...} 在構造器之前執行,每次 new 都執行。super() 隱式調用父類無參構造器,觸發父類實例初始化。public final class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return INSTANCE; }
}
public final class Singleton {
private static volatile Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) INSTANCE = new Singleton();
}
}
return INSTANCE;
}
}
public final class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() { return Holder.INSTANCE; }
}
public enum Singleton {
INSTANCE;
public void doSomething() {}
}
import static java.lang.Math.*; // 導入所有靜態成員
import static java.lang.Math.PI; // 導入單個
// 直接使用
double r = sqrt(2); // 無需 Math.sqrt
double area = PI * r * r;