类版本1
package com.classLoad.version1;
public class Version {
public void testVersion()
{
System.out.println("我是版本1");
}
}
类版本2
package com.classLoad.version2;
public class Version {
public void testVersion()
{
System.out.println("我是版本2");
}
}
类加载器1
public class ClassLoad_1 extends ClassLoader {
// 读入源文件转换为字节数组
private byte[] getSource(String filename) {
File file = new File(filename);
int length = (int) file.length();
byte[] contents = new byte[length];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
int r = fis.read(contents);
if (r != length) {
throw new IOException("IOException:无法读取" + filename);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return contents;
}
// 编译文件
public boolean compile(String javaFile) {
System.out.println("正在编译" + javaFile);
int ret = 0;
try {
// 调用系统命令编译文件
Process process = Runtime.getRuntime().exec("javac " + javaFile);
process.waitFor();
ret = process.exitValue();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return ret == 0;
}
// 重写findclass
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> clazz = null;
// 将文件的.替换为/,例如com.lyl.reflect.Reflect被替换为com/lyl/reflect/Reflect
String fileStub = name.replace(".", "/");
String path = System.getProperty("user.dir");
//可以理解为不同路径下的同名类
fileStub = path + "\\bin\\com\\classLoad\\version1\\" + fileStub;
// java源文件名
String javaFileName = fileStub + ".java";
// 编译后的class文件名
String classFileName = fileStub + ".class";
File javaFile = new File(javaFileName);
File classFile = new File(classFileName);
// 当指定JAVA源文件存在,且class文件不存在,
// 或者java源文件的修改时间比class文件修改时间晚则重新编译
if (javaFile.exists()
&& (!classFile.exists() || javaFile.lastModified() > classFile
.lastModified())) {
// 如果编译失败,或者class文件不存在
if (!compile(javaFileName) || !classFile.exists()) {
throw new ClassNotFoundException("ClassNotFoundException:"
+ javaFileName);
}
}
// 如果CLASS文件按存在,系统负责将该文件转换成Class对象
if (classFile.exists()) {
byte[] raw = getSource(classFileName);
// 将ClassLoader的defineClass方法将二进制数据转换成Class对象
int divindex = name.indexOf("\\");
String javafilename = null;
// 如果是某个盘里面的文件,要去掉文件的盘符
if (divindex != -1) {
javafilename = name.substring(divindex + 1, name.length());
}
// 将字节数组转换为class实例
clazz = defineClass(javafilename, raw, 0, raw.length);
}
// 如果clazz为null,表明加载失败,则抛出异常
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return clazz;
}
}
类加载器2
public class ClassLoad_2 extends ClassLoader {
// 读入源文件转换为字节数组
private byte[] getSource(String filename) {
File file = new File(filename);
int length = (int) file.length();
byte[] contents = new byte[length];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
int r = fis.read(contents);
if (r != length) {
throw new IOException("IOException:无法读取" + filename);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return contents;
}
// 编译文件
public boolean compile(String javaFile) {
System.out.println("正在编译" + javaFile);
int ret = 0;
try {
// 调用系统命令编译文件
Process process = Runtime.getRuntime().exec("javac " + javaFile);
process.waitFor();
ret = process.exitValue();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return ret == 0;
}
// 重写findclass
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> clazz = null;
// 将文件的.替换为/,例如com.lyl.reflect.Reflect被替换为com/lyl/reflect/Reflect
String fileStub = name.replace(".", "/");
String path = System.getProperty("user.dir");
//可以理解为不同路径下的同名类
fileStub = path + "\\bin\\com\\classLoad\\version2\\" + fileStub;
// java源文件名
String javaFileName = fileStub + ".java";
// 编译后的class文件名
String classFileName = fileStub + ".class";
File javaFile = new File(javaFileName);
File classFile = new File(classFileName);
// 当指定JAVA源文件存在,且class文件不存在,
// 或者java源文件的修改时间比class文件修改时间晚则重新编译
if (javaFile.exists()
&& (!classFile.exists() || javaFile.lastModified() > classFile
.lastModified())) {
// 如果编译失败,或者class文件不存在
if (!compile(javaFileName) || !classFile.exists()) {
throw new ClassNotFoundException("ClassNotFoundException:"
+ javaFileName);
}
}
// 如果CLASS文件按存在,系统负责将该文件转换成Class对象
if (classFile.exists()) {
byte[] raw = getSource(classFileName);
// 将ClassLoader的defineClass方法将二进制数据转换成Class对象
int divindex = name.indexOf("\\");
String javafilename = null;
// 如果是某个盘里面的文件,要去掉文件的盘符
if (divindex != -1) {
javafilename = name.substring(divindex + 1, name.length());
}
// 将字节数组转换为class实例
clazz = defineClass(javafilename, raw, 0, raw.length);
}
// 如果clazz为null,表明加载失败,则抛出异常
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return clazz;
}
}
测试类
public class Test {
// 定义主方法
public static void main(String[] args) throws ClassNotFoundException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException {
ClassLoader ccl1 = new ClassLoad_1();
ClassLoader ccl2 = new ClassLoad_2();
// 加载需要运行的类
Class<?> clazz1 = ccl1.loadClass("Version");
Class<?> clazz2 = ccl2.loadClass("Version");
Method main1 = clazz1.getMethod("testVersion");
Object o1 = clazz1.newInstance();
main1.invoke(o1);
Method main2 = clazz2.getMethod("testVersion");
Object o2 = clazz2.newInstance();
main2.invoke(o2);
}
}
输出数据:
我是版本1
我是版本2