在逛论坛的看到很多的朋友在讨论staic块,进去瞧瞧,感觉有点雾里看花。我也不知道static块到底有什么用,何时用。学习下吧,好象JDBC就用到这些东西。
一般情况下,如果有些代码必须在项目启动的时候就要被执行,这种情况上就需要使用静态代码块,这种代码是主动执行的,写个例子看看static块什么时候被执行
1.StaticTest
- package com.test.statictest;
- public class StaticTest {
- /** 构造方法*/
- public StaticTest() {
- System.out.println("构造函数被执行了!");
- }
- /** 静态代码快*/
- static {
- System.out.println("静态代码块被执行了!");
- //show();
- }
- /** 静态方法*/
- public static void show(){
- System.out.println("静态方法被执行了!");
- }
- }
2.Main
- package com.test.statictest;
- public class Main {
- public static void main(String[] args) throws ClassNotFoundException {
- Main main = new Main();
- //加载类
- Class.forName("com.test.statictest.StaticTest");
- Class.forName("com.test.statictest.StaticTest");
- }
- }
结果输出
静态代码块被执行了!
在测试类里我加载了2次StaticTest类,按理说"静态代码块被执行了!"这句话应执行二次,但只输出了一次。
再看看别的
- package com.test.statictest;
- public class Main {
- public static void main(String[] args) throws ClassNotFoundException {
- Main main = new Main();
- //加载类
- Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader());
- //Class.forName("com.test.statictest.StaticTest");
- }
- }
结果:
静态代码块被执行了!
这两个语句是等价的,执行的结果相同。
把Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader())中的true改为false,代表加载类的时候不初始化静态代码块的内容,只能在这个类被实例化的时候才能初始化
Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码块.
看看JDBC是怎么对Class.forName解释的:
we just want to load the driver to jvm only, but not need to user the instance of driver, so call Class.forName(xxx.xx.xx) is enough, if you call Class.forName(xxx.xx.xx).newInstance(), the result will same as calling Class.forName(xxx.xx.xx), becauseClass.forName(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the instacne you will never use in usual, so you need not to create it.
翻译:
我们只是想加载这个驱动到JVM,并不需要实例化这个驱动,因此调用Class.forName(xxx.xxx.xx) 足够,如果你调用Class.forName(xxx.xxx.xxx).newInstance(),结果和调用Class.forName(xxx.xxx.xxx)是一样的,因为Class.forName(xxx.xxx.xxx).newInstance() 会首先加载驱动并创建实例,但是这个实例通常你决不会用到,所有你不需要创建它。
这是java源码。