静态代码块是如何执行的?一般用在什么地方?

Jvm的类加载机制中,我们说过有一个阶段是初始化(Initialization),这个阶段的应用类加载器(Application or App ClasLoader)会收集所有的静态代码块并执行,而且只执行一次。所以这里有一个误区,很多人认为Java静态代码块是在类被加载时自动执行,这是错误的,需要注意的是,静态代码块只在类加载的初始化阶段执行。
类被加载了,不一定会执行静态代码块,详情看代码:

public class ClassLoaderTest {
	public static void main(String[] args) {
		System.out.println("main()函数===" + LoaderTest.class);
	}
}

class LoaderTest {
	static {
		System.out.println(">>>静态代码块执行了没有<<<");
	}
}

那么,静态代码块是如何执行的呢?
静态代码块会在类加载的初始化阶段执行,而且只执行一次。

如果继承父类,则会先执行父类中的静态代码块,然后再执行子类中的静态代码块;

实例对象时,会先执行父类中的非静态代码块,父类中的构造方法,然后再执行子类中的非静态代码块,子类中的构造方法!

public class Father {
	static {
		System.out.println(">>>Father静态代码块<<<");
	}

	{
		System.out.println(">>>Father非静态代码块<<<");
	}

	public Father() {
		System.out.println(">>>Father无参构造<<<");
	}
}
public class TestSon extends Father {

	static {
		System.out.println(">>>TestSon静态代码块<<<");
	}

	{
		System.out.println(">>>TestSon非静态代码块<<<");
	}

	public TestSon() {
		System.out.println(">>>TestSon无参构造<<<");
	}
	
	public static void main(String[] args) {
		System.out.println("TestSon的main()函数");
		TestSon son1 = new TestSon();
		System.out.println("--------------------");
		TestSon son2 = new TestSon();
	}
}

静态代码块一般用在什么地方?
1)在项目启动时,加载某个类,对数据进行数据化(如初始化基础数据或数据库连接池)。 

// 输出服务器编码
static {
		Charset defaultCharset = Charset.defaultCharset();
		String name = defaultCharset.name();
		System.out.println("\n"+"\t"+"当前服务器采用的字符集是:" + name);
	}

2)工具类中使用static静态代码块进行初始化,当第一次访问工具类时,就会先进行初始化(只会执行一次),保存到静态全局属性中,当其他类再次访问时,将直接使用初始化数据(如获取一个单例sessionFactory)。

public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    private static final ThreadLocal session = new ThreadLocal();

    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章