前言
7.1 概述
7.2 类加载的时机
class SuperClass {
static {
System.out.println("SuperClass init!");
}
public static int value = 123;
}
class SubClass extends SuperClass {
static {
System.out.println("SubClass init!");
}
}
public class D1 {
public static void main(String[] args) {
System.out.println(SubClass.value);
}
}
-----
SuperClass init!
123
--- vm Options
-XX:+TraceClassLoading
-XX:+TraceClassLoading
java -XX:+PrintFlagsFinal -version | findstr Trace
开启后输出结果如图所示
public static void main(String[] args) {
// System.out.println(SubClass.value);
SuperClass[] sca = new SuperClass[10];
}
class ConstClass {
static {
System.out.println("ConstClass init!");
}
public static final String HELLOWORLD = "hello world";
}
public class D1 {
public static void main(String[] args) {
// System.out.println(SubClass.value);
// SuperClass[] sca = new SuperClass[10];
System.out.println(ConstClass.HELLOWORLD);
}
}
-----
hello world
7.3 类加载的过程
7.3.1 加载
7.3.2 验证
7.3.3 准备
7.3.4 解析
public class FieldResolution {
interface Interface0 {
int A = 0;
}
interface Interface1 extends Interface0 {
int A = 1;
}
interface Interface2 {
int A = 2;
}
static class Parent implements Interface1 {
public static int A = 3;
}
static class Sub extends Parent implements Interface2 {
public static int A = 4;
}
public static void main(String[] args) {
System.out.println(Sub.A);
}
}
7.3.5 初始化
public class D3 {
static class Parent {
public static int A = 1;
static {
A = 2;
}
}
static class Sub extends Parent {
public static int B = A;
}
public static void main(String[] args) {
System.out.println(Sub.B);
}
}
-----
2
public class D4 {
static class DeadLoopClass {
static {
// 如果不加上这个if语句,编译器将提示“Initializer does not complete normally” 并拒绝编译
if (true) {
System.out.println(Thread.currentThread() + "init DeadLoopClass");
while (true) {
}
}
}
}
public static void main(String[] args) {
Runnable script = new Runnable() {
public void run() {
System.out.println(Thread.currentThread() + "start");
DeadLoopClass dlc = new DeadLoopClass();
System.out.println(Thread.currentThread() + " run over");
}
};
Thread thread1 = new Thread(script);
Thread thread2 = new Thread(script);
thread1.start();
thread2.start();
}
}
-----
Thread[Thread-1,5,main]start
Thread[Thread-0,5,main]start
Thread[Thread-1,5,main]init DeadLoopClass
7.4 类加载器
7.4.1 类与类加载器
public class ClassLoaderTest {
public static void main(String[] args) throws Exception {
ClassLoader myLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if (is == null) {
return super.loadClass(name);
}
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
} catch (IOException e) {
throw new ClassNotFoundException(name);
}
}
};
Object obj = myLoader.loadClass("com.example.common.jvm.c7.ClassLoaderTest").newInstance();
System.out.println(obj.getClass());
System.out.println(obj instanceof ClassLoaderTest);
}
}
----
class com.example.common.jvm.c7.ClassLoaderTest
false
7.4.2 双亲委派模型
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先,检查类是否已经加载
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
7.4.3 破坏双亲委派模型
7.5 Java模块化系统
7.5.1 模块的兼容性
7.5.2 模块化下的类加载器