JVM中类的初始化时机

只有对类进行主动引用,才会触发其初始化方法,而除此之外的引用方式称之为被动引用,不会触发其初始化方法

1.主动引用

这里先定义一个Utils(名字随便起的,不要见怪)作为被测试类

package day12;

/**
 * @author :weihuanwen
 * @date :Created in 2019/5/23 00:14
 * @description :
 * @version: 1.0
 */
public class Utils {
    //定义静态final变量
    public static final int sfVar = 100;
    //定义实例变量
    public int instanceVar = 1;
    //定义静态变量
    public static int staticVar = 10;
    //通过静态代码块是否执行验证此类是否加载
    static {
        System.out.println("Utils类被加载!");
    }
    /**
     * 定义静态方法
     */
    public static void staticMethod(){
        System.out.println("执行了静态方法!");
    }
    /**
     * 定义成员方法
     */
    public void instanceMethod(){
        System.out.println("执行了成员方法");
    }
}

①设置静态成员变量时

package day12;

public class test01 {
    public static void main(String[] args) {
        Utils.staticVar = 10;
    }
}

输出结果显示:

Utils类被加载!

②调用静态方法时

package day12;

public class test01 {
    public static void main(String[] args) {
        Utils.staticMethod();
    }
}

输出结果显示:

Utils类被加载!
执行了静态方法!

③实例化对象时

package day12;

public class test01 {
    public static void main(String[] args) {
        Utils utils = new Utils();
    }
}

输出结果显示:

Utils类被加载!

④读取静态成员变量时

package day12;

public class test01 {
    public static void main(String[] args) {
        System.out.println(Utils.staticVar);
    }
}

输出结果显示:

Utils类被加载!

10

⑤反射调用时

package day12;

public class test01 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("day12.Utils");
    }
}

输出结果显示:

Utils类被加载!

⑥初始化子类时,会先初始化其父类

package day12;
/**
 * 父类
 */
public class SuperClass {
    static {
        System.out.println("父类被加载!");
    }
}
package day12;
/**
 * 子类
 */
public class SubClass extends SuperClass{
    static {
        System.out.println("子类被加载!");
    }
}
package day12;

public class test01 {
    public static void main(String[] args){
       new SubClass();
    }
}

输出结果显示:

父类被加载!
子类被加载!

⑦Java虚拟机启动时被标明为启动类的类(含main()方法的类)

package day12;

public class Mark {
    static {
        System.out.println("标记类Mark被加载!");
    }

    public static void main(String[] args) {
        //这里不写代码,直接自行该main()方法
    }
}
class ReferFirst{
    static {
        System.out.println("第一个参照类被加载!");
    }
}
class ReferSecond{
    static {
        System.out.println("第二个参照类被加载!");
    }
}

输出结果显示:

标记类Mark被加载!

2.被动引用:

除了以上七种情况外的都尊徐被动引用,这里只介绍几种被动引用

①通过子类引用父类的静态字段,不会导致子类的初始化

package day12;
/**
 * 父类
 */
public class SuperClass {
    public static int staticVar = 10;
    static {
        System.out.println("父类被加载!");
    }
}
package day12;
/**
 * 子类
 */
public class SubClass extends SuperClass{
    static {
        System.out.println("子类被加载!");
    }
}
package day12;

public class test01 {
    public static void main(String[] args){
        System.out.println(SubClass.staticVar);
    }
}

输出结果显示:

父类被加载!
10

②读取static final 修饰的变量时,不会导致类的初始化

package day12;

public class test01 {
    public static void main(String[] args){
        System.out.println(Utils.sfVar);
    }
}

输出结果显示:

100

****常量在编译阶段会存入调用类的常量池中,本质没有直接引用到定义的常量类中,因此不会触发定义的常量类初始化

③通过数组定义来引用,不会导致类的初始化

package day12;

public class Person {
    static {
        System.out.println("Person类被加载!");
    }
}
package day12;

public class test01 {
    public static void main(String[] args){
        Person[] personarr = new Person[10];
    }
}

输出结果显示:

无输出结果

④通过集合定义来引用,不会导致类的初始化(道理同③)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值