【Java SE】Java中的static关键字总结
·
Java中的static关键字总结
在Java编程语言中,static是一个非常重要的关键字,它用于定义类级别的成员。被static修饰的成员属于类本身,而不是类的某个具体实例。这意味着无论创建多少个类的对象,静态成员在内存中只有一份拷贝,被所有对象共享。本文将详细介绍Java中static的四种主要用法:静态变量、静态方法、静态初始化块和静态内部类。
静态变量(类变量)
定义与特点
静态变量是使用static关键字修饰的变量,也称为类变量。它与普通实例变量的最大区别在于:
- 属于类而非对象:静态变量在内存中只有一个副本,被该类的所有对象共享
- 类加载时初始化:静态变量在类加载到JVM时完成初始化,且在整个程序运行期间只初始化一次
- 直接通过类名访问:无需创建对象,直接使用
类名.静态变量名的方式访问
public class Counter {
static int count = 0; // 静态变量,记录创建的对象数量
public Counter() {
count++; // 每次创建对象时,count增加
}
}
public class Main {
public static void main(String[] args) {
System.out.println("初始对象数量: " + Counter.count); // 输出: 0,无需创建对象
Counter obj1 = new Counter();
System.out.println("创建obj1后: " + obj1.count); // 输出: 1
Counter obj2 = new Counter();
System.out.println("创建obj2后: " + Counter.count); // 输出: 2(使用类名访问)
}
}
静态方法(类方法)
定义与特点
静态方法是使用static关键字修饰的方法,也称为类方法。其主要特点包括:
- 类级别调用:可以直接通过类名调用,无需创建对象
- 访问限制:只能直接访问类的静态成员(静态变量和其他静态方法)
- 不能使用this和super:静态方法中不存在当前对象的引用
访问限制的深入理解
静态方法不能直接访问实例成员的根本原因在于生命周期不同:静态方法在类加载时就存在,而实例成员只有在对象创建后才存在。如果需要在静态方法中访问实例成员,必须先创建对象。
public class Demo {
int instanceVar = 20; // 实例变量
void instanceMethod() {
System.out.println("实例方法被调用");
}
// 错误示例:静态方法直接访问实例成员
static void wrongStaticMethod() {
// System.out.println(instanceVar); // 编译错误!
// instanceMethod(); // 编译错误!
}
// 正确示例:通过对象访问实例成员
static void correctStaticMethod() {
Demo obj = new Demo(); // 先创建对象
System.out.println("通过对象访问实例变量: " + obj.instanceVar);
obj.instanceMethod(); // 通过对象调用实例方法
}
}
实用示例
public class MathUtils {
// 工具方法,无需创建对象即可使用
public static int add(int a, int b) {
return a + b;
}
public static double circleArea(double radius) {
return Math.PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
int sum = MathUtils.add(5, 3); // 直接通过类名调用
double area = MathUtils.circleArea(2.5); // 无需创建MathUtils对象
System.out.println("5 + 3 = " + sum); // 输出: 8
System.out.println("圆面积: " + area); // 输出: 19.634...
}
}
静态初始化块
语法格式
public class MyClass {
static {
// 静态代码块的内容
System.out.println("这是静态代码块");
}
}
执行时机⭐
静态初始化块是用static关键字修饰的代码块,用于执行类的初始化操作。其特点如下:
- 类加载时执行:当JVM第一次加载类时执行
- 只执行一次:在整个程序生命周期中仅执行一次
- 优先于main方法:在main方法执行之前执行
- 顺序执行:如果有多个静态代码块,按定义顺序执行
具体原理双亲委派模型
注意事项
- 静态代码块中不能直接访问非静态成员
- 静态代码块中不能使用
this和super关键字 - 静态代码块中不能抛出受检异常
- 如果类中包含多个静态代码块,它们会按顺序执行
主要用途
静态代码块常用于以下场景:
- 初始化静态变量:为静态成员变量赋初始值
- 加载配置文件:读取properties或XML配置文件
- 建立数据库连接:创建数据库连接池
- 注册驱动:如JDBC驱动注册
public class DatabaseConfig {
private static String url;
private static String username;
private static String password;
// 静态代码块 - 加载配置文件
static {
System.out.println("静态代码块开始执行:加载配置文件");
// 模拟读取配置文件
url = "jdbc:mysql://localhost:3306/mydb";
username = "root";
password = "123456";
try {
// 注册JDBC驱动
Class.forName("com.mysql.jdbc.Driver");
System.out.println("数据库驱动注册成功");
} catch (ClassNotFoundException e) {
System.out.println("数据库驱动注册失败");
}
System.out.println("静态代码块执行完成");
}
public static void main(String[] args) {
System.out.println("main方法开始执行");
System.out.println("数据库URL: " + url);
System.out.println("用户名: " + username);
}
}
执行结果:
静态代码块开始执行:加载配置文件
数据库驱动注册成功
静态代码块执行完成
main方法开始执行
数据库URL: jdbc:mysql://localhost:3306/mydb
用户名: root
静态内部类
定义与特点
静态内部类是使用static修饰的内部类,它与普通内部类有显著区别:
- 不依赖外部类实例:可以直接创建静态内部类的对象,无需先创建外部类对象
- 访问限制:只能访问外部类的静态成员,不能直接访问实例成员
- 可包含静态成员:静态内部类可以有自己的静态变量和方法
- 外部类名访问:通过
外部类名.内部类名的方式访问
public class Company {
private static String companyName = "Tech Corp";
private String address = "Beijing";
// 静态内部类
public static class Employee {
private String name;
private static int employeeCount = 0; // 静态内部类可以有自己的静态成员
public Employee(String name) {
this.name = name;
employeeCount++;
}
public void display() {
// 可以访问外部类的静态成员
System.out.println("公司名称: " + companyName);
// 不能直接访问外部类的实例成员
// System.out.println(address); // 编译错误!
System.out.println("员工姓名: " + name);
System.out.println("员工总数: " + employeeCount);
}
public static void showCompanyInfo() {
System.out.println("公司: " + companyName);
}
}
// 非静态内部类(对比用)
public class Department {
private String deptName;
public Department(String deptName) {
this.deptName = deptName;
}
public void showInfo() {
// 非静态内部类可以访问外部类的所有成员
System.out.println("公司: " + companyName + ", 地址: " + address);
System.out.println("部门: " + deptName);
}
}
}
public class Main {
public static void main(String[] args) {
// 创建静态内部类对象 - 不需要外部类实例
Company.Employee emp1 = new Company.Employee("张三");
Company.Employee emp2 = new Company.Employee("李四");
emp1.display();
System.out.println("---");
// 调用静态内部类的静态方法
Company.Employee.showCompanyInfo();
System.out.println("--- 分割线 ---");
// 创建非静态内部类对象 - 需要先创建外部类实例
Company company = new Company();
Company.Department dept = company.new Department("技术部");
dept.showInfo();
}
}
应用场景
- 辅助类的封装,当内部类不需要访问外部类实例成员时
- 构建器模式(Builder Pattern)的实现
- 与外部类逻辑紧密相关但可独立使用的工具类
static的核心特性
| 类型 | 属于 | 访问方式 | 初始化时机 | 内存特点 |
|---|---|---|---|---|
| 静态变量 | 类 | 类名.变量名 | 类加载时 | 一份拷贝,所有对象共享 |
| 静态方法 | 类 | 类名.方法名 | 类加载时 | 存储在方法区 |
| 静态块 | 类 | 自动执行 | 类加载时 | 执行后释放 |
| 静态内部类 | 类 | 外部类.内部类 | 使用时加载 | 独立于外部类实例 |
例题
例题1
以下代码的输出结果是?
public class Test {
public int aMethod() {
static int i = 0; // 这行有错误:static不能修饰局部变量
i++;
return i;
}
public static void main(String args[]) {
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
静态变量不能在方法内部声明
public int aMethod() {
static int i = 0; // ❌ 错误:不能在方法内部使用static修饰局部变量
i++;
return i;
}
在Java中,static关键字不能用于修饰局部变量。静态变量属于类级别,必须在类中直接声明,而不能在方法、构造方法或代码块内部声明。
如果要实现类似的功能(计数方法被调用的次数),正确的写法应该是:
public class Test {
static int i = 0; // 静态变量定义在类中,而不是方法中
public int aMethod() {
i++;
return i;
}
public static void main(String args[]) {
Test test = new Test();
test.aMethod(); // 第一次调用,i=1
int j = test.aMethod(); // 第二次调用,i=2
System.out.println(j); // 输出 2
}
}
更多推荐




所有评论(0)