您的位置:首页 > 编程语言 > Java开发

JAVA 动态加载

2008-11-04 17:18 309 查看
package dynamicClassLoader;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;

public class MyClassLoader extends ClassLoader {

 // 定义哈希表(Hashtable)类型的变量,用于保存被载入的类数据。
 Hashtable loadedClasses;

 public MyClassLoader() {
  loadedClasses = new Hashtable();
 }

 public synchronized Class loadClass(String className, boolean resolve)
   throws ClassNotFoundException {
  Class newClass;
  byte[] classData;

  // 检查要载入的类数据是否已经被保存在哈希表中。
  newClass = (Class) loadedClasses.get(className);
  // 如果类数据已经存在且resolve值为true,则解析它。
  if (newClass != null) {
   if (resolve)
    resolveClass(newClass);
   System.out.println(className + " is exist!");
   return newClass;
  }

  // 先用(系统)父亲的classloader来加载,当在当前classpath下找不到该类字节码,则用自定义classLoader
  try {
   newClass = findSystemClass(className);
   return newClass;
  } catch (ClassNotFoundException e) {
   System.out.println(className + " is not a system class!");
  }
  // 如果不是系统类,试图从网络中指定的URL地址载入类。
  try {
   // 用自定义方法载入类数据,存放于字节数组classData中。
   classData = getClassData(className);
   // 由字节数组所包含的数据建立一个class类型的对象。
   newClass = defineClass(classData, 0, classData.length);
   if (newClass == null)
    throw new ClassNotFoundException(className);
  } catch (Exception e) {
   throw new ClassNotFoundException(className);
  }

  // 如果类被正确载入,则将类数据保存在哈希表中,以备再次使用。
  loadedClasses.put(className, newClass);
  // 如果resolve值为true,则解析类数据。
  if (resolve) {
   resolveClass(newClass);
  }
  return newClass;
 }

 protected byte[] getClassData(String className) throws Exception {
  InputStream inputStream = null;
  byte[] data = null;
  if (true) {
   data = this.getDataFromFile(className);
  } else {
   data = this.getDataFromURL(className);
  }
  return data;
 }

 // 这个方法从网络中载入类数据。
 private byte[] getDataFromURL(String urlClassName) throws IOException {
  byte[] data;
  int length;
  try {
   // 从网络中采用URL类的方法, 载入指定URL地址的类的数据。
   URL url = new URL(urlClassName.endsWith(".class") ? urlClassName
     : urlClassName + ".class");
   URLConnection connection = url.openConnection();
   InputStream inputStream = connection.getInputStream();
   length = connection.getContentLength();

   data = new byte[length];
   inputStream.read(data);
   inputStream.close();
   return data;
  } catch (Exception e) {
   throw new IOException(urlClassName);
  }
 }

 private byte[] getDataFromFile(String className) throws IOException {
  byte[] data;
  File file = new File(className);
  InputStream inputStream = new BufferedInputStream(new FileInputStream(
    className));
  int length = (int) file.length();
  data = new byte[length];
  inputStream.read(data);
  inputStream.close();
  return data;
 }

 public static void main(String[] args) throws Exception {
  MyClassLoader mcl = new MyClassLoader();
  Class test = mcl.loadClass("D://Test.class",true);//把编译好的 Test.class,复制到d:下
  Constructor constructor = test.getConstructor(new Class[0]);
  Object object = constructor.newInstance(new Class[0]);
  Method method = test.getDeclaredMethod("printTest",new Class[0]);
  method.invoke( object,new Object[0]);
 }
}
------------------以下是 Test.java--------------

package dynamicClassLoader;

public class Test {

 public Test(){
  System.out.println("in constructor");
 }

 public void printTest () {
  System.out.println("in print method");
 }

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息