Java 中的 static 关键字

在 C++ 中, static 关键字只可以用来修饰变量和方法。Java 中, static 关键字可以修饰类,变量和方法。

静态类和非静态类

  • 静态类 (static class a.k.a. nested static class)
  • 非静态类 (non-static class a.k.a. nested class)

在 Java 中,静态类和非静态类的概念是区别不同的嵌套类的,嵌套类所在的外部类被称为 enclosing class 。

1
2
3
4
5
class EnclosingClass {
static class NestedClass {
//...
}
}

在 C++ 中,所有的类都是静态类,所以 Java 中的静态类的行为应该与 C++ 中的嵌套类一样。所有的静态类都可以拿到类的外面写。静态类的唯一用途就是使代码结构看起来更清晰。由于静态嵌套类和关联类的实例无关,所以只能访问关联类的静态变量。

而非静态类嵌套类才是真正意义上的内部类。可以认为非静态嵌套类是属于每个关联类的实例的。内部类可以访问所有父类的变量。

内部类中不允许声明静态方法,如果有这个需求应该写在关联类里。

下面的代码展示了如何实例化静态嵌套类和非静态嵌套类。

1
2
3
4
5
6
7
8
9
10
11
12
13
class OutterClass {
static class InnerStaticClass {
//...
}
class InnerClass {
//...
}
}
// in other method
OutterClass.InnerStaticClass instance_static = new OutterClass.InnerStaticClass();
OutterClass outter_instance = new OutterClass();
OutterClass.InnerClass instance_non_static = outter_instance.new InnerClass();

静态方法和非静态方法

Java 中,静态方法就是类方法,就是可以通过类名调用的方法(也可通过实例调用)。而非静态方法就是通过实例来调用的方法。

因为不需要通过实例来调用静态方法,所以在调用静态方法的时候甚至可以不需要实例。这也是 main 函数在 Java 中必须是静态方法的原因。

静态变量

成员变量为静态变量时,所有类的实例共享同一个变量。可以通过实例访问,也可以通过类名访问。
方法中的变量为静态变量时,只在第一次进入方法时为该变量分配空间,方法返回后不释放空间;第二次进入后仍然可以访问之前为这个变量分配的地址。