package com.jvm;
/**
*
* 类初始化场景
*
* 虚拟机中严格规定了有且只有5种情况必须对类进行初始化。
*
* <pre>
* 1.执行new、getstatic、putstatic和invokestatic指令;
* 2. 使用reflect对类进行反射调用;
* 3.初始化一个类的时候,父类还没有初始化,会事先初始化父类;
* 4.启动虚拟机时,需要初始化包含main方法的类;
* 5. 在JDK1.7中,如果java.lang.invoke.MethodHandler实例最后的解析结果REF_getStatic、REF_putStatic
* 、REF_invokeStatic的方法句柄,并且这个方法句柄对应的类没有进行初始化;
* </pre>
*
* @author hao
* @since 7.0
*/
public class _initTest {
@SuppressWarnings("unused")
public static void main(String[] args) {
System.out.println("main init !");
System.out.println();
// -1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
System.out.println("// -1. ----------//");
System.out.println(Child.a);
System.out.println();
// -2. 定义对象数组,不会触发该类的初始化。
System.out.println("// -2. ----------//");
Array[] arrays = new Array[10];
System.out.println();
// -3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
System.out.println("// -3. ----------//");
System.out.println(Const.a);
System.out.println();
// -4. 通过类名获取Class对象,不会触发类的初始化。
System.out.println("// -4. ----------//");
Class<?> c_Cat_Tom = Cat_Tom.class;
System.out.println();
// -5.
// 通过Class.forName加载指定类时,如果指定参数initialize为false时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。
System.out.println("// -5. ----------//");
try {
Class<?> clazz = Class.forName("com.jvm.Cat_H", false, Cat_H.class.getClassLoader());
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println();
// -6. 通过ClassLoader默认的loadClass方法,也不会触发初始化动作
System.out.println("// -6. ----------//");
try {
new ClassLoader() {
}.loadClass("com.jvm.Cat_T");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
}
}
// -1. ------------------------------------------------------------------//
class Parent {
public static int a = 100;
static {
System.out.println("Parent init !");
}
}
class Child extends Parent {
static {
System.out.println("Child init !");
}
}
// -2. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Array {
private String name;
private int age;
static {
System.out.println("Array init !");
}
}
// -3. ------------------------------------------------------------------//
class Const {
public static final int a = 100;
static {
System.out.println("Const init !");
}
}
// -4. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Cat_Tom {
private String name;
private int age;
static {
System.out.println("Cat_Tom is load !");
}
}
@SuppressWarnings("all")
class Cat_Jack {
private String name;
private int age;
static {
System.out.println("Cat_Jack is load !");
}
}
// -5. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Cat_H {
private String name;
private int age;
static {
System.out.println("Cat_H is load !");
}
}
// -6. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Cat_T {
private String name;
private int age;
static {
System.out.println("Cat_T is load !");
}
/**
*
* 类初始化场景
*
* 虚拟机中严格规定了有且只有5种情况必须对类进行初始化。
*
* <pre>
* 1.执行new、getstatic、putstatic和invokestatic指令;
* 2. 使用reflect对类进行反射调用;
* 3.初始化一个类的时候,父类还没有初始化,会事先初始化父类;
* 4.启动虚拟机时,需要初始化包含main方法的类;
* 5. 在JDK1.7中,如果java.lang.invoke.MethodHandler实例最后的解析结果REF_getStatic、REF_putStatic
* 、REF_invokeStatic的方法句柄,并且这个方法句柄对应的类没有进行初始化;
* </pre>
*
* @author hao
* @since 7.0
*/
public class _initTest {
@SuppressWarnings("unused")
public static void main(String[] args) {
System.out.println("main init !");
System.out.println();
// -1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
System.out.println("// -1. ----------//");
System.out.println(Child.a);
System.out.println();
// -2. 定义对象数组,不会触发该类的初始化。
System.out.println("// -2. ----------//");
Array[] arrays = new Array[10];
System.out.println();
// -3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
System.out.println("// -3. ----------//");
System.out.println(Const.a);
System.out.println();
// -4. 通过类名获取Class对象,不会触发类的初始化。
System.out.println("// -4. ----------//");
Class<?> c_Cat_Tom = Cat_Tom.class;
System.out.println();
// -5.
// 通过Class.forName加载指定类时,如果指定参数initialize为false时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。
System.out.println("// -5. ----------//");
try {
Class<?> clazz = Class.forName("com.jvm.Cat_H", false, Cat_H.class.getClassLoader());
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println();
// -6. 通过ClassLoader默认的loadClass方法,也不会触发初始化动作
System.out.println("// -6. ----------//");
try {
new ClassLoader() {
}.loadClass("com.jvm.Cat_T");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
}
}
// -1. ------------------------------------------------------------------//
class Parent {
public static int a = 100;
static {
System.out.println("Parent init !");
}
}
class Child extends Parent {
static {
System.out.println("Child init !");
}
}
// -2. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Array {
private String name;
private int age;
static {
System.out.println("Array init !");
}
}
// -3. ------------------------------------------------------------------//
class Const {
public static final int a = 100;
static {
System.out.println("Const init !");
}
}
// -4. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Cat_Tom {
private String name;
private int age;
static {
System.out.println("Cat_Tom is load !");
}
}
@SuppressWarnings("all")
class Cat_Jack {
private String name;
private int age;
static {
System.out.println("Cat_Jack is load !");
}
}
// -5. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Cat_H {
private String name;
private int age;
static {
System.out.println("Cat_H is load !");
}
}
// -6. ------------------------------------------------------------------//
@SuppressWarnings("all")
class Cat_T {
private String name;
private int age;
static {
System.out.println("Cat_T is load !");
}
}