在 Java 中,static 关键字是一个非常基础且重要的概念,它属于类本身,而不是类的某个实例(对象)。

被 static 修饰的成员(变量、方法、代码块)属于“大家共用的”,在类加载时就已经存在,不需要创建对象就能使用。
以下是 static 关键字的四个主要使用场景及详细解析:
静态变量
也称为类变量。
- 特点:被
static修饰的成员变量,被该类的所有对象共享,在内存中只有一个副本。 - 区别:非静态变量(实例变量)是每个对象独享的,每
new一个对象,都会开辟新的内存空间存储实例变量。 - 访问方式:
类名.变量名(推荐) 或对象名.变量名。
代码示例:

class Student {
String name; // 实例变量:每个学生名字不同
static String school = "清华大学"; // 静态变量:所有学生共享同一个学校
}
public class Main {
public static void main(String[] args) {
// 不需要创建对象,直接通过类名访问
System.out.println(Student.school);
Student s1 = new Student();
Student s2 = new Student();
// 修改静态变量,会影响所有对象
Student.school = "北京大学";
System.out.println(s1.school); // 输出:北京大学
System.out.println(s2.school); // 输出:北京大学
}
}
静态方法
- 特点:属于类,不属于对象。
- 调用方式:
类名.方法名()(推荐)。 - 核心限制(重要):
- 静态方法中不能使用
this和super关键字(因为this代表当前对象,而静态方法调用时可能还没有对象)。 - 静态方法只能访问静态成员(静态变量和静态方法),不能直接访问非静态成员(实例变量或实例方法)。
- 原因:非静态成员依赖于对象存在,而静态方法不依赖于对象。
- 非静态方法可以访问静态成员。
- 静态方法中不能使用
代码示例:
class Tool {
public static int add(int a, int b) {
return a + b;
}
// 错误示范:静态方法调用非静态变量会报错
// public void show() {
// System.out.println(name); // 编译错误
// }
}
public class Main {
public static void main(String[] args) {
// 直接通过类名调用,无需 new Tool()
int result = Tool.add(5, 3);
System.out.println(result); // 8
}
}
常见的静态方法:Math.random(), Arrays.sort(), main() 方法。
静态代码块
- 作用:用于初始化类,通常用于加载配置文件、初始化静态变量等。
- 执行时机:类加载时执行一次,且只执行一次。
- 执行顺序:如果有多个静态代码块,按照定义顺序依次执行。
代码示例:
class Database {
static {
System.out.println("1. 静态代码块执行:初始化数据库连接...");
}
public Database() {
System.out.println("3. 构造方法执行");
}
}
public class Main {
public static void main(String[] args) {
new Database();
new Database(); // 第二次 new 时,静态代码块不会再执行
}
}
/* 输出:
1. 静态代码块执行:初始化数据库连接...
3. 构造方法执行
3. 构造方法执行
*/
静态内部类
- 特点:在一个类内部定义的静态类。
- 区别:
- 普通内部类:隐式持有外部类的引用(可以访问外部类的非静态成员)。
- 静态内部类:不持有外部类的引用(只能访问外部类的静态成员)。
- 优点:减少了内存开销,避免了内存泄漏(常见于 Android 开发或单例模式)。
代码示例:
class Outer {
private static String msg = "Hello";
static class Inner {
public void print() {
// 只能访问外部类的静态变量
System.out.println(msg);
}
}
}
public class Main {
public static void main(String[] args) {
// 创建静态内部类对象不需要先创建外部类对象
Outer.Inner inner = new Outer.Inner();
inner.print();
}
}
静态导入 (Static Import)
这是 JDK 1.5 引入的语法糖。
- 作用:导入类的某个静态方法或静态变量,使用时可以直接写方法名,不用写类名。
代码示例:
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Main {
public static void main(String[] args) {
// 直接使用 PI 和 random(),不需要 Math.PI
System.out.println(PI);
System.out.println(random());
}
}
static 的核心记忆点
- 归属:属于类,不属于对象。
- 内存:在方法区(JDK 8 以后在堆中的 Class 对象里)只有一份,全局共享。
- 生命周期:随着类加载而加载,随着类卸载而销毁(生命周期极长)。
- 限制:静态无法直接访问非静态(因为静态存在时,非静态的对象可能还没出生)。
面试常见问题:static 能修饰构造方法吗?
不能。 构造方法是用来创建对象的,它属于对象层面的初始化逻辑,而 static 是类层面的,如果构造方法变成静态的,它就无法初始化对象的实例变量,这就失去了构造方法的意义。
