JVM 运行流程 1.如何跨平台 (JVM针对不同的平台生成不同的虚拟机) Java源程序通过 Javac编程生成.class文件, 加载到JVM内存的堆中,通过被JVM解析成能被不同平台支持的指令, 2. JVM基本结构 类加载器 ClassLoader 符合要求负责加载到内存中
执行引擎 execution engine 负责运行 解析
运行数据区 核心
本地接口 native 被 native 对融合不同开发语言的原生库为JAVA所用 无需重复开发
3.类的装载 : 加载,连接 (验证,准备,解析),初始化,使用,卸载 class存储类的结构 堆中 初始化: 执行类的构造器<clinit> 为类的静态变量和静态代码块初始化值 安源码的顺序执行,如果静态代码块在前,则,只能写不能读 反之没要求 构造器是构造类的 构造方法是实例化对象 先执行构造器, 通过父类的加载器先加载, 4.为什么 类的加载器是双亲委派模型 避免重复加载 首先父类的类加载先加载,如果没找到,在去找发起者的类加载器,
避免重复加载,父类加载器已经加载成功,子类的类加载器无需再次加载 安全,String是根类加载的 Obj
JDK 已有的类加载器
BootStrapClassloader JVM的启动加载器 自启的 c++写的 >>主要加载 rt.jar 一堆jar 在java中用Null代替Extensionclassloader 加载%lib/ext/*.jar% Appclassloader 都是继承的 classpath自定义类加载器 自定义的加载路径 重写findclass方法实现自定义类加载器java.lang.ClassLoader.class
传的是类的二进制字节流 包名加类名
/ /首先,检查是否已经加载了类 Class<?> c = findLoadedClass(name);
自定义类加载器 重点是重写findclass方法
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;
public class MyclassLoader extends ClassLoader{ private String path; //加载类的路径 private String name; public MyclassLoader(String path, String name) { super(); //让系统类加载器成为该类的父类 this.path = path; this.name = name; }
public MyclassLoader(ClassLoader parent,String path, String name) { super(parent); this.path = path; this.name = name; }
/* * 加载定义的类 * * */ @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // TODO Auto-generated method stub byte[] data = null; try { data = readClassFileToByteArray(name); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return this.defineClass(name, data, 0, data.length); }
/* * 获取。class文件的字节数组 * * * */ private byte[] readClassFileToByteArray(String name2) throws IOException { InputStream is=null; byte[]returnData=null; name = name.replaceAll("\\.","/"); String filePath=this.path+ name +".class"; File file=new File(filePath); ByteArrayOutputStream os=new ByteArrayOutputStream(); try { is=new FileInputStream(file); int tmp=0; while((tmp =is.read())!= -1){ os.write(tmp); } returnData=os.toByteArray(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { is.close(); os.close(); } return returnData; // TODO Auto-generated method stub } }