类加载时机的基础知识 (懒得写,直接用别人的了,他的代码没有分开,故我写了这篇博客,为像我这样的菜鸟)
7.2 类加载的时机
代码清单7-1,被动引用的例子之一
package cn.chapter7;
public class SuperClass{
static{
System.out.println("SuperClass init!");
}
public static int value = 123;
}
package cn.chapter7;
public class SubClass extends SuperClass{
static{
System.out.println("SubClass init!");
}
}
package cn.chapter7;
/*
* 被动使用类字段演示1
* 通过子类引用父类的静态字段,不会导致子类初始化
*
* 非主动使用类字段演示
*/
public class NotInitialization {
public static void main(String[] args) {
System.out.println(SubClass.value);
}
}
运行结果:
SuperClass init!
123
运行结果分析, 点击这里(要找一下)
代码清单7-2, 被动使用类字段演示二
package cn.chapter7;
/*
* 被动使用类字段演示二
* 通过数组定义来引用类 ,不会触发此类的初始化
*/
public class NotInitialization2 {
public static void main(String[] args) {
SuperClass [] sca = new SuperClass[10];
}
}
运行结果:
(啥都没有)
代码清单7-3,被动使用类字段演示三
package cn.chapter7;
/*
* 被动使用类字段演示三
* 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化
*/
public class ConstClass {
static{
System.out.println("ConstClass init!");
}
public static final String HELLOWORLD = "hello world!";
}
package cn.chapter7;
/*
* 被动使用类字段演示三
* 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化
*/
public class ConstClass {
static{
System.out.println("ConstClass init!");
}
public static final String HELLOWORLD = "hello world!";
}
运行结果:
hello world!
接口的加载过程与类的加载过程有一些不同:
字段解析
代码清单7-4 , 字段解析
package cn.chapter7;
/*
* 字段解析,书p184
*/
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;
}
public class Sub extends Parent implements Interface2{
//public static int A = 4;
}
public static void main(String[] args) {
System.out.println(Sub.A);
}
}
报错:
The field Sub.A is ambiguous(二义性)
7.3.5 初始化
代码清单7-5, <clinit>()方法执行顺序
父类中定义的静态语句块要优先于子类的变量复制操作,字段B的值将是2而不是1
书上的源代码有问题啊,在子类要用static修饰,不然报错
package cn.chapter7;
/*
* <clinit>()方法执行顺序
* 父类中定义的静态语句块要优先于子类的变量复制操作,字段B的值将是2而不是1
* 书上的源代码有问题啊,在子类要用static修饰,不然报错
*/
public class Solution7_5 {
static class Parent{
public static int A = 1;
static{
A = 2;
}
}
public static class Sub extends Parent{
public static int B = A;
}
public static void main(String[] args) {
System.out.println(Sub.B);
}
}
输出
2
代码清单7-6, 字段解析
package cn.chapter7;
/*
* 代码清单7-6, 字段解析
*/
public class Solution7_6 {
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-0,5,main]start
Thread[Thread-1,5,main]start
Thread[Thread-0,5,main]init DeadLoopClass
7.4 类加载器
7.4.1 类与类加载器
代码清单7-7, 不同的类加载器对instanceof关键字运算结果的影响。
package cn.chapter7;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ClassLoader;
/*
*代码清单7-7, 不同的类加载器对instanceof关键字运算结果的影响。
*/
public class ClassLoaderTest {
public static void main(String [] args) throws Exception{
ClassLoader myLoader = new ClassLoader(){//这个ClassLoader要import java.lang.ClassLoader;
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException{
try{
String fileName = name.substring(name.lastIndexOf(".")+1);
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("cn.chapter7.ClassLoaderTest").newInstance();
System.out.println(obj.getClass());
System.out.println(obj instanceof cn.chapter7.ClassLoaderTest);
}
}
输出:
class cn.chapter7.ClassLoaderTest
true
应该是false啊,书上还解释了,为什么同样的代码,我的输出true,不科学啊????想不通
7.4.2 双亲委派模型
代码清单7-8 双亲委派模型的实现