Java中自定義類加載器(雙親委派機制)

同一個類,被不同的加載器加載,jvm會認爲也是不相同的類.

package tk.javazhangwei.test;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/***
 * 自定義文件系統加載器(採用雙親委派機制)
 * @author zw
 *
 */
public class FileSystenClassLoader extends ClassLoader {

	private String rootDir;

	public FileSystenClassLoader(String rootDir) {
		super();
		this.rootDir = rootDir;
	}
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		Class<?> c =findLoadedClass(name);
		//西安查詢有沒有加載過這個類。如果已經加載,則直接返回加載好的類。else加載新的類 
		if(c!=null) {
			return c;
		}else {
			ClassLoader parent = this.getParent();
			try {
				c =parent.loadClass(name);//委派給父類加載
			} catch (Exception e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
			}
			if(c!=null) {
				return c;
			}else {
				byte[] classData =getClassData(name);
				if(classData == null) {
					throw new ClassNotFoundException();
				}else {
					c=defineClass(name, classData, 0, classData.length);
				}
			}
		}
		return c;
	}
	
	
	
	private byte[] getClassData(String name) {
		
		String path = rootDir +"/"+name.replace(".", "/")+".class";
		InputStream is = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try {
			 is = new FileInputStream(path);
			 byte[] data = new byte[1024];
			 int len=0;
			 while((len=is.read(data))!=-1) {
				 bos.write(data,0,len);
			 }
			 bos.flush();
			 bos.close();
			 is.close();
			 return bos.toByteArray();
		
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

package tk.javazhangwei.test;
/***
 * 測試自定義的FileSystemClassLoder
 * @author zw
 *
 */
public class Demo03 {
	public static void main(String[] args) throws ClassNotFoundException {
		FileSystenClassLoader fc = new FileSystenClassLoader("D:/mycode/test/");
		Class c = fc.loadClass("tk.javazhangwei.HelloWorld");
		
		FileSystenClassLoader fc1 = new FileSystenClassLoader("D:/mycode/test/");
		Class c1 = fc1.loadClass("tk.javazhangwei.HelloWorld");
		
		Class c2 = fc1.loadClass("java.lang.String");
		
		System.out.println(c);
		System.out.println(c.hashCode());
		System.out.println(c1.hashCode());//同一個類,被不同的加載器加載,jvm會認爲也是不相同的類
		
		
		System.out.println(c.getClassLoader());//自定義加載器加載
		System.out.println(c2.getClassLoader());//引導類加載器
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章