在 Java 中,static
是一个修饰符,用于定义与类相关(而非对象实例相关)的成员。以下是核心知识点和用法:
一、四大用途
-
静态变量(类变量)
- 作用:属于类,而非实例。所有实例共享同一副本。
- 内存分配:类加载时在方法区内存中分配。
- 示例:
public class Counter {static int count = 0; // 静态变量public Counter() { count++; } }
Counter c1 = new Counter(); // count=1 Counter c2 = new Counter(); // count=2 (共享)
-
静态方法(类方法)
- 规则:
- 只能访问静态成员(变量/方法)。
- 不能使用
this
或super
。 - 可通过类名直接调用。
- 示例:
public class MathUtils {public static int add(int a, int b) {return a + b;} } // 调用:MathUtils.add(3, 5);
- 规则:
-
静态代码块
- 作用:在类加载时执行一次,用于初始化静态资源。
- 执行顺序:按定义顺序执行。
- 示例:
public class Database {static {System.out.println("加载数据库驱动..."); // 类加载时执行} }
-
静态内部类
- 特点:
- 不依赖外部类实例。
- 无法访问外部类的非静态成员。
- 示例:
public class Outer {static class Nested { // 静态内部类void print() { System.out.println("Nested"); }} } // 使用:Outer.Nested obj = new Outer.Nested();
- 特点:
二、关键特性
-
生命周期
- 从类加载开始,到 JVM 结束销毁。
- 比实例成员的生命周期长。
-
内存分配
- 静态变量/方法:存储在方法区(JDK 8+ 的元空间)。
- 实例变量/方法:存储在堆内存的对象中。
-
访问限制
- 静态方法中 不能直接访问非静态成员(需要先创建对象)。
- 非静态方法可以自由访问静态成员。
三、使用场景
-
共享数据配置
public class AppConfig {public static final String API_KEY = "ABC123"; // 全局常量 }
-
工具类设计
public class StringUtils {private StringUtils() {} // 防止实例化public static boolean isEmpty(String s) { ... } }
-
单例模式
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;} }
四、常见误区
-
重写问题
static
方法不能被重写(Override),只支持方法隐藏(Method Hiding):class Parent {static void print() { System.out.println("Parent"); } } class Child extends Parent {static void print() { System.out.println("Child"); } // 隐藏父类方法 }
-
多态失效
静态方法在编译时绑定,不存在运行时多态:Parent obj = new Child(); obj.print(); // 输出 "Parent"(编译时类型决定)
-
线程安全问题
多个线程同时修改静态变量需同步:public class Counter {private static int count;public static synchronized void increment() { count++; } // 加锁 }
五、与 final
结合
- 静态常量:固定不变的值(如数学常量)
public class Constants {public static final double PI = 3.1415926; }
六、总结
特性 | static 成员 | 非静态成员 |
---|---|---|
归属 | 类 | 对象实例 |
内存分配时机 | 类加载时 | 创建对象时 |
访问方式 | 类名.成员 或对象访问 | 必须通过对象访问 |
生命周期 | 与类相同 | 与对象相同 |
多态支持 | 不支持(静态绑定) | 支持(动态绑定) |
最佳实践:优先用 static
定义工具方法、常量,避免滥用导致代码耦合或内存泄漏。