jvm解析编译过的class资料
jvm解析编译过的class文件
jvm解析编译过的class文件:
说明MyClassLoader类为核心类主要来加载编译后的文件。
Test.class.rar中表示编译的Test.class文件。
TestClass.rar中的TestClass类为最终测试类。
Test.rar中的Test类主要包括一个方法在jvm解析时通过加载Test.class文件最终执行Test类中的方法。
本例中Test.class文件存放在D:\Users\Test.class,文件位置你可以随便存放。
package com.cld;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
public class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent, String baseDir) {
super(parent);
}
/**
* 使用指定的二进制名称查找类
* @param name 类的二进制名称
* @return Class 得到的 Class 对象
* @throws ClassNotFoundException
*/
protected Class findClass(String name) throws ClassNotFoundException {
// TODO Auto-generated method stub
byte[] bytes = loadClassBytes(name);
//将一个 byte 数组转换为 Class 类的实例。必须分析 Class,然后才能使用它。
Class theClass = defineClass(name, bytes, 0, bytes.length);
if (theClass == null)
throw new ClassFormatError();
return theClass;
}
/**
* 返回所要加载文件路径
* @return String 所要加载文件路径
*/
private String getClassFile() {
return "D:/Users/Test.class";
}
/**
* 返回所加载的资源文件字节数组
* @param className 所需要的类的二进制名称,如果不知道此名称,则该参数为 null
* @return 字节数组
* @throws ClassNotFoundException
*/
private byte[] loadClassBytes(String className)
throws ClassNotFoundException {
String classFile = getClassFile();
try {
FileInputStream fis = new FileInputStream(classFile);
//用于读取、写入、映射和操作文件的通道(FileChannel)
FileChannel filec = fis.getChannel();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//可写入字节的通道(WritableByteChannel)
//Channels.newChannel(baos)构造向给定流写入字节的信道
WritableByteChannel outC = Channels.newChannel(baos);
//字节缓冲区ByteBuffer.allocateDirect(1024)分配新的直接字节缓冲区
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (true) {
//filec.read(buffer)将字节序列从此通道读入给定的缓冲区
int i = filec.read(buffer);
if (i == 0 || i == -1) {
break;
}
buffer.flip();
outC.write(buffer);
buffer.clear();
}
fis.close();
return baos.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
throw new ClassNotFoundException(className);
}
}
}
jvm解析编译过的class文件:
说明MyClassLoader类为核心类主要来加载编译后的文件。
Test.class.rar中表示编译的Test.class文件。
TestClass.rar中的TestClass类为最终测试类。
Test.rar中的Test类主要包括一个方法在jvm解析时通过加载Test.class文件最终执行Test类中的方法。
本例中Test.class文件存放在D:\Users\Test.class,文件位置你可以随便存放。
package com.cld;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
public class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent, String baseDir) {
super(parent);
}
/**
* 使用指定的二进制名称查找类
* @param name 类的二进制名称
* @return Class 得到的 Class 对象
* @throws ClassNotFoundException
*/
protected Class findClass(String name) throws ClassNotFoundException {
// TODO Auto-generated method stub
byte[] bytes = loadClassBytes(name);
//将一个 byte 数组转换为 Class 类的实例。必须分析 Class,然后才能使用它。
Class theClass = defineClass(name, bytes, 0, bytes.length);
if (theClass == null)
throw new ClassFormatError();
return theClass;
}
/**
* 返回所要加载文件路径
* @return String 所要加载文件路径
*/
private String getClassFile() {
return "D:/Users/Test.class";
}
/**
* 返回所加载的资源文件字节数组
* @param className 所需要的类的二进制名称,如果不知道此名称,则该参数为 null
* @return 字节数组
* @throws ClassNotFoundException
*/
private byte[] loadClassBytes(String className)
throws ClassNotFoundException {
String classFile = getClassFile();
try {
FileInputStream fis = new FileInputStream(classFile);
//用于读取、写入、映射和操作文件的通道(FileChannel)
FileChannel filec = fis.getChannel();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//可写入字节的通道(WritableByteChannel)
//Channels.newChannel(baos)构造向给定流写入字节的信道
WritableByteChannel outC = Channels.newChannel(baos);
//字节缓冲区ByteBuffer.allocateDirect(1024)分配新的直接字节缓冲区
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (true) {
//filec.read(buffer)将字节序列从此通道读入给定的缓冲区
int i = filec.read(buffer);
if (i == 0 || i == -1) {
break;
}
buffer.flip();
outC.write(buffer);
buffer.clear();
}
fis.close();
return baos.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
throw new ClassNotFoundException(className);
}
}
}