package com.zkh;
//测试对静态代码块和
public class ClassLoaderTest {
{
System.out.println("主调类的非静态代码块");
}
static {
System.out.println("主调类的静态代码块");
}
public ClassLoaderTest() {
System.out.println("主调类的构造方法");
}
public static void main(String[] args) {
ClassLoaderTest test = new ClassLoaderTest();
Children children = new Children();
}
}
class Parent {
{
System.out.println("父类的非静态代码块");
}
static {
System.out.println("父类的静态代码块");
}
public Parent() {
System.out.println("父类的构造方法");
}
}
class Children extends Parent{
{
System.out.println("子类的非静态代码块");
}
static {
System.out.println("子类的静态代码块");
}
public Children() {
System.out.println("子类的构造方法");
}
}
结果为:
主调类的静态代码块
主调类的非静态代码块
主调类的构造方法
父类的静态代码块
子类的静态代码块
父类的非静态代码块
父类的构造方法
子类的非静态代码块
子类的构造方法
非静态代码块在每次实例化一个对象时,都会调用一次,静态代码块只会调用一次
示例二:
package com.zkh.classloader;
/**
* 类的准备阶段是为类变量分配内存并设置默认值,在此例中类变量st = null, b = 0
* 类的初始化阶段做的是执行类构造器(
* 类构造器是编译器收集所有静态语句块和类变量的赋值语句合并产生的,
* 编译器收集的顺序是由语句在源文件中出现的顺序所决定的
* )
* 因此执行第一条静态变量的赋值语句 test = new MyClassLoaderTest();此时会进行对象的初始化
* 对象的初始化是先初始化成员变量,再执行构造方法,
* 因此设置 a为110 -> 打印2 -> 执行构造方法(打印3,此时a已经赋值110,但
* b只是设置了默认值0,并未完成赋值动作)
* 等对象的初始化完成后继续执行类构造器的语句
* 结果:
* 2
* 3
* a = 110,b = 0
* 1
* 4
*
*/
public class MyClassLoaderTest {
public static void main(String[] args) {
staticFunction();
}
static MyClassLoaderTest test = new MyClassLoaderTest();
static {
System.out.println("1");
}
{
System.out.println("2");
}
MyClassLoaderTest() {
System.out.println("3");
System.out.println("a = " + a + ",b = " + b);
}
private static void staticFunction() {
System.out.println("4");
}
int a = 110;
static int b = 112;
}