一 static 代表着什么
在 java 中,static 表示静态的意思,并不是全局的意思,在 java 中不存在所谓的全局变量的概念。static 可以用来修饰成员变量、成员方法和代码块。当 JVM 加载一个类的时候,若该类中含有静态的成员变量或成员方法时,那么这些变量和方法就会被保存在一个“方法区”中,供全局调用,只有一份。
二 堆栈、堆、方法区(范围和存储信息)
堆栈
- 每个线程包含一个堆栈,其中存放的是基本数据的对象和自定义对象的引用(引用不是对象本身)
- 每个栈中的数据都是私有的,其它线程无法访问
堆
- 堆中存储的全部都是对象,每个对象都包含一个与之对应的 class 的信息(为了获取 class 的操作指令)
- JVM 只有一个堆,被所有线程共享
方法区/静态区
- 方法区中包含所有的 class 和 static 变量
- 方法区和堆一样只有一个,被所有线程共享
三 static 的使用
static 成员变量
static 变量会随着类的加载被初始化,它在内存中只存在一份,可以通过类名直接来访问。
static 成员方法
static 的初始化和 static 成员变量一样。static 方法不可以被 abstract 修饰,因为 static 方法在类加载的时候就已经存在了。
static 代码块
static 代码块也被称为是静态代码块,随着类的加载而被执行,可以放在类中的任何位置。
static 代码块和 static 方法最大的不同就是
- static 方法是在被调用的时候才会被执行
- static 代码块是在类的加载的时候就会被执行
四 对象的初始化顺序
先来看段代码
class Parent {
static String name = "hello";
{
System.out.println("parent block");
}
static {
System.out.println("parent static block");
}
public Parent() {
System.out.println("parent constructor");
}
}
class Child extends Parent {
static String childName = "hello";
{
System.out.println("child block");
}
static {
System.out.println("child static block");
}
public Child() {
System.out.println("child constructor");
}
}
public class StaticIniBlockOrderTest {
public static void main(String[] args) {
new Child();//语句(*)
}
}
/**output
parent static block
child static block
parent block
parent constructor
child block
child constructor
**/
顺序:
- 执行父类中的静态代码块
- 执行本类中的静态代码块
- 执行父类中的非静态代码块
- 执行父类中的构造方法
- 执行本类中的非静态代码块
- 执行本类中的构造方法