Java static关键字
static
是 Java 中的一个关键字,主要用于修饰 变量、方法、代码块 和 内部类,作用是将成员定义为类级别,即属于类本身,而不是某个具体的实例对象。这里介绍一下static的主要用法和特点。
1. static
变量
由类共享,所有对象访问的都是同一块内存,不因为对象不同而改变。
在类加载时就被分配内存,生命周期与类一致。
存储在方法区(JDK8 之后是元空间 Metaspace)。
class Student {
static int totalStudents = 0; // 静态变量,所有对象共享
String name;
Student(String name) {
this.name = name;
totalStudents++; // 每创建一个 Student 对象,计数 +1
}
void display() {
System.out.println(name + ",当前总学生数:" + totalStudents);
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
s1.display(); // Alice,当前总学生数:2
s2.display(); // Bob,当前总学生数:2
}
}
2. static
方法
无需创建对象即可调用,可以通过类名.方法名() 直接调用。
不能访问非静态成员(非静态变量、非静态方法),非静态成员属于实例,而
static
方法属于类。不能使用
this
或super
关键字,this
代表当前实例,而static
方法不依赖实例。
class MathUtil {
static int square(int x) {
return x * x;
}
}
public class Main {
public static void main(String[] args) {
int result = MathUtil.square(5); // 直接用类名调用
System.out.println("5 的平方是:" + result);
}
}
3. static
代码块
类加载时执行且只执行一次。
用于初始化静态变量或执行类级别的初始化操作。
class Database {
static String url;
// 静态代码块
static {
url = "jdbc:mysql://localhost:3306/test";
System.out.println("静态代码块执行,数据库 URL 初始化完成!");
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Database.url); // 访问静态变量,触发类加载
}
}
4. static
内部类
静态内部类不依赖外部类对象,可以直接创建。
不能访问外部类的非静态成员,但可以访问静态成员。
class Outer {
static class Inner {
void show() {
System.out.println("我是静态内部类的方法");
}
}
}
public class Main {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner(); // 直接创建内部类对象
inner.show();
}
}
例
public class Test extends Base{
static{
System.out.println("test static");
}
public Test(){
System.out.println("test constructor");
}
public static void main(String[] args) {
new Test();
}
}
class Base{
static{
System.out.println("base static");
}
public Base(){
System.out.println("base constructor");
}
}
执行顺序解析
类加载阶段(
static
代码块执行)程序从
main()
方法开始执行,此时 Test 还未被加载,因此 需要先加载Test
类。由于 Test 继承自 Base,必须先加载 Base。
加载 Base 类,发现Base类有静态代码块,执行Base类的静态代码块
加载 Test 类,发现Test类有静态代码块,执行Test类的静态代码块
创建对象阶段(构造方法执行)
main()
方法执行new Test();
,开始实例化 Test 对象由于Test继承自Base,所以必须先调用 Base 的构造方法,然后调用Test的构造方法
最终的输出顺序
base static
test static
base constructor
test constructor
评论