第7章虚拟机类加载机制+深入理解java虚拟机

类加载时机的基础知识  (懒得写,直接用别人的了,他的代码没有分开,故我写了这篇博客,为像我这样的菜鸟

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 双亲委派模型的实现

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值