所有的Java虚拟机必须实现在每个类或接口被Java程序 “ 首次主动使用 ” 时才初始化他们

原文:https://www.cnblogs.com/fanjie/p/6916784.html

Java程序对类的使用方式可分为两种
主动使用
被动使用

被动使用以后再讲,这里说说什么是主动使用,java对类的主动使用有六种情况

1、创建类的实例

2、访问某个类或接口的静态变量,或者对该静态变量赋值

3、调用类的静态方法

4、反射(如Class.forName(“com.shengsiyuan.Test”))

5、初始化一个类的子类(先初始化所有的父类,最后初始化本身,接口除外,类初始化的时候,它所实现的接口不会初始化,就算字接口初始化,父接口也不会初始化,只有当程序调用接口的静态变量的时候才会导致接口的初始化)(接口初始化规则

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

 这里唯一需要解释的可能就是最后一个,什么叫被标记为启动类的类呢

比如我们有一个Hello.java文件,但是里面包含了class Hello ,class Person1 ,class Person2,我们在控制台运行的时候会写java Hello,这个class Hello就是被标记为启动类的类。简单说就是拥有main方法的类

以上的六个活动在第一次发生时,都会促使jvm虚拟机加载类。

除了上述六种情况以外,其他情况都属于类的被动调用,主动调用和被动调用的区别请看下面代码

class Test2{
  public static final int n = 2;
  static{
    System.out.println("test");
  }
}

public class Test1 {
  public static void main(String[] args) {
    System.out.println(Test2.n);
  }
}

大家思考一下会出现什么?不管你的答案是什么,正确答案是2 。 Test2中的静态代码块是没有运行的,因为Test2并没有初始化

注意,这里的final关键字不可缺少,我们知道变量被关键字fianl修饰之后就不可修改,亦即此变量相当于编译期常量(是相当于并非就是常量),常量在java编译期已经确定,不需要初始化,但是把fianal去掉,或者把 final int n = 2 改为 final int n = new Random()。,运行的结果将变为 test  ,2 ,因为n的值为变量或者n值在编译期不能确定,就必须经过初始化才能使用n的值。

猜你喜欢

转载自www.cnblogs.com/DDiamondd/p/10963096.html