1、static{}(即static块),会在类被加载的时候执行,且仅会被执行一次,一般用来初始化静态变量和调用静态方法。
public class Hello { public static final int i; static{ i=1; System.out.println("static 块语句"); } public Hello() { // TODO Auto-generated constructor stub } static void say(){ System.out.println("say----------------"); } }
static块语句的执行时机(即何为加载?)
1、实例化一个类的时候
Hello t=new Hello();
2、类装载
Class.forName("main.Hello");
或者
Hello t=(Hello)Class.forName("main.Hello").newInstance();
3、调用类的静态方法或静态变量
Hello.say();
static块语句在say的前面执行。
4、如果静态变量在定义的时候就赋给了初值(如 static int X=100),那么赋值操作也是在类加载的时候完成的,并且当一个类中既有static{}又有static变量的时候,同样遵循“先定义先执行”的原则;
public static int x=500; static{ System.out.println("static 块语句--x="+x); i=1; x=90; System.out.println("static 块语句--x="+x); }
输出Hello.x
static 块语句--x=500
static 块语句--x=90
90
5、如果定义final成员变量不直接赋值,则必须在static块语句赋值,否则出错
注意:
1、调用类的已赋值静态常量的时候,是不会加载类的,即不会执行static{}语句块
(这是java虚拟机的规定,当访问类的静态常量时,如果编译器可以计算出常量的值,则不会加载类,否则会加载类)
2、用Class.forName()形式的时候,我们也可以自己设定要不要加载类,如将Class.forName("Test")改为 Class.forName("Test",false,StaticBlockTest.class.getClassLoader()),你会发现程序什么都没有输出,即Test没有被加载,static{}没有被执行。
类加载:Java命令的作用是启动虚拟机,虚拟机通过输入流,从磁盘上将字节码文件(.class文件)中的内容读入虚拟机,并保存起来的过程就是类加载。
Done!