static 关键字
目录
陈述
首先,一定要注意发音**‘stætɪk**,word天,中文发音不行,英语发音也不行,你还能说啥?Japanese吗?😕……
用 static
修饰的变量或方式是从属于类的,而没有用static
修饰的则是从属于实例对象的。
static
可用于:变量、方法、语句块、内部类、导包1。
- 静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它;静态变量在内存中只存在一份。而每创建一个实例就会产生一个实例变量,它与该实例同生共死。
- 静态方法:在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法(
abstract
)。静态方法只能访问所属类的静态字段和静态方法,方法中不能有this
和super
关键字。 - 静态语句块:在类初始化时运行一次。
- 静态内部类:可通过
类名.静态内部类
访问,实际上已经是个独立的类了,但是它能访问外部类的私有静态变量或方法。不能访问外部类的非静态的变量和方法。而非静态内部类依赖于外部类的实例,要通过Outer.Inner inner = outer.new Inner();
,其中Outer outer = new Outer();
,还可通过Outer.this
访问外部类的实例,而this
是指的内部类实例自己2。 - 静态导包:使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低,一般是
import static com.xxx.ClassName.*
。
关于初始化顺序,一定要记住:静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。
先静态后实例,父在子前,静态看顺序:
- 父类静态变量、静态语句块
- 子类静态变量、静态语句块
- 父类实例变量、普通语句块
- 父类构造方法
- 子类实例变量、普通语句块
- 子类构造方法
验证
// 静态导入
import java.util.HashMap;
import static java.lang.Math.PI;
import static java.lang.Math.pow;
public class StaticTest {
private String name = "Hello Static";
private final String age = "28";
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.println();
staticTest.print();
StaticTest.Secret secret = staticTest.new Secret(); // !!! 注意这里的语法 !!! 直接写成 new Secret() 会报错,必须依赖外部类!
System.out.println(secret.a);
}
// 局部内部类
private void println() {
class PartInner {
public PartInner() {
System.out.println("PartInner.");
System.out.println("Final Age:" + age);
}
}
PartInner partInner = new PartInner();
System.out.println(MyMath.circleArea(2));
}
// 匿名内部类
private void print() {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>() {
// 实例语句块
{
put(1,2); put(3,4);
}
@Override
public Integer put(Integer key, Integer value) {
return super.put(key, value);
}
};
System.out.println(map.get(3));
}
// (非静态)成员内部类
private class Secret {
public int a;
private int b;
private String name; // 同名
Secret() {
System.out.println(name);
name = "Inner Name";
System.out.println(StaticTest.this.name);
}
}
// 静态(成员)内部类
static class MyMath {
public static double circleArea(int r) {
return PI * pow(r, 2);
}
}
}
输出:
PartInner.
Final Age:28
12.566370614359172
4
null
Hello Static
0
思考
能修饰外部类的修饰符只有四种:public
、default
、abstract
、final
。
外部类的上一级程序单位是包,因此它只有两个使用范围:包内和包外,因此它只能用
public
(表示可以在全局位置使用)和默认修饰符(default
,表示只能被同一个包的其他类使用)修饰3。
内部类根据其分类又有不同。
- 成员内部类:就像是类里的成员变量。无条件访问外部类所有成员,对于同名的需要
外部类.this.成员
进行访问。内部类的修饰符可以是:public
、protected
、default
、private
、static
。- 静态内部类:就像是静态成员变量。不依赖外部类。可用访问修饰符修饰4。
- 局部内部类:就像是方法里的局部变量。不能有访问修饰符。只能访问外部类的变量只能是
final
,方法生命周期的问题。 - 匿名内部类:就像是方法里的局部变量。不能有访问修饰符。唯一没有构造器的类。