因为main所在的类会在jvm启动时,自动被加载,所以写在另一类做测试。
//Test.java
public class Test {
public static void main(String[] args) {
new People();
new People();
// System.out.println(People.name);
// People.test();
// System.out.println(People.Head.name);
}
}
public class People {
{
System.out.println("111");
}
static {
System.out.println("3");
name="3";
}
public static String name="1";
static {
System.out.println("2");
name="2";
}
public static void test(){
System.out.println("test");
}
static class Head{
public static String name="head1";
static {
System.out.println("head2");
name="head3";
}
}
{
System.out.println("222");
}
class Body{
}
}
class Child extends People{
}
- 静态块 (或构造块) 与 普通块
静态块,加载类时(读取类编译的class文件时)执行【一次】
常用作初始化静态属性,因为静态属性只能做简单赋值,比如基本类型或者new,不能写多行代码复杂赋值
static {
}
没有static是普通块,对象【每次】new会执行
{
}
- 静态块与静态属性的执行顺序,按照在代码中先后顺序执行,类class文件加载后,就好从头遍历文件【顺序执行】静态块或静态属性赋值
System.out.println(People.name)
输出最下面静态块的值 2
- 不管内部类是普通类还是静态类,还是内部子类,编译后都会放到【单独】的class文件,所以可以想到,直接访问静态内部类【不会加载外部类class】,直接访问外部类的静态方法,【不会加载内部类class】
People.test(); //没有初始化内部静态类
System.out.println(People.Head.name); //没有初始化外部类
【总结】
jvm会在需要这个类时,去加载这个类编译后的class文件,内部类有单独文件存放,只是名字特殊。jvm读取类的class后会按照代码顺序执行静态块与静态属性。静态块主要用于初始化静态属性