java classLoader 理解三

第二篇博文主要讲解了ClassLoader的一些原理性的东西,本篇主要分析一些实战性的东西.                                                                                                                                                       一般 获取ClassLoader会有如下三种方式:

        	1.this.getClass().getClassLoader();   
        	2.ClassLoader.getSystemClassLoader(); 
		3.Thread.currentThread().getContextClassLoader();

第一种方法主要通过Class文件获取,最常见,

第二种方法通过ClassLoader类的静态方法getSystemClassLoader()获取,该方法返回就是AppClassLoader(个人觉得),

第三种方法通过当前线程获取,如果启动该线程的类在classPath下,获取到的自然就是AppClassLoader,如果启动线程的类在java.ext.dir目录下,获取到的就是extClassLoader,除了获取ClassLoader,第三种方式也可set  ClassLoader,看代码,

class MyClassLoader extends URLClassLoader {
		
        MyClassLoader(URL[] urls, ClassLoader parent) {
        	
		    super(urls, parent);
		}
		
		public static void main(String args[]) throws Exception{
			
			File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin");
			URL url=file.toURL();
			URL urls[]=new URL[]{url};
			MyClassLoader classLoader=new MyClassLoader(urls,ClassLoader.getSystemClassLoader());
			Thread.currentThread().setContextClassLoader(classLoader);
			Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest");
			System.out.println(Thread.currentThread().getContextClassLoader());
		}
}

自定义了一个ClassLoader,指定加载目录,指定父加载器, 指定加载目录url2肯定不是当前项目(既MyClassLoader这个类所属项目)的目录,因为当前项目ClassPath下面的文件肯定会被appClassLoader这个父加载器先加载.


接下来说说自定义ClassLoader,上代码先,

代码1:

class MyClassLoader extends URLClassLoader {
		
		
                MyClassLoader(URL[] urls, ClassLoader parent) {
		    super(urls, parent);
		}
		
		public static void main(String args[]) throws Exception{
			
			File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin");
			URL url=file.toURL();
			URL urls[]=new URL[]{url};
			MyClassLoader classLoader=new MyClassLoader(urls,ClassLoader.getSystemClassLoader());			
			Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest");
			
			Object object=newClass.newInstance();
			Method method=newClass.getMethod("setName",String.class);
			method.invoke(object, "jake");
			
			Method method2=newClass.getMethod("sayName");
			method2.invoke(object);
			classLoader.close();
			
		}

}
代码2:

class MyClassLoader2 extends ClassLoader {
		
        MyClassLoader2(ClassLoader parent) {
        	super(parent);
		}
        
        public Class<?> findClass(String name)  {  //ps: 该方法实现还是有问题的
        	
        	FileInputStream input=null;
        	ByteOutputStream out=null;
        	String oName=name;
        	
			try {
				name=name.replace(".", File.separator).concat(".class");
	        	File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin\\"+name);
	        	
	        	input=new FileInputStream(file);
	        	out=new ByteOutputStream();
	        	
				byte by[]=new byte[1024];
				int len=0;
				while((len=input.read(by))!=-1){
					out.write(by, 0, len);
				}
				
				byte bt[]=out.getBytes();
				return defineClass(oName,bt, 0, bt.length);
				
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				if(input!=null){
					try {
						input.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(out!=null){
					out.close();
				}
			}
			
        	return null;
        }
        
		public static void main(String args[]) throws Exception{
			
			MyClassLoader2 classLoader=new MyClassLoader2(ClassLoader.getSystemClassLoader());
			Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest");
			
			Object object=newClass.newInstance();
			Method method=newClass.getMethod("setName",String.class);
			method.invoke(object, "jake");
			
			Method method2=newClass.getMethod("sayName");
			method2.invoke(object);
			
		}
}


代码一是通过继承URLClassLoader这个ClassLoader,我们常见的appClassLoader,extClassLoader就是继承这个类加载器,URLClassLoader内部实现了findClass(String name)这个方法,载入自己需要的class文件,  载入后转化为我们的Class对象则可以调用顶层ClassLoader内部loadClass(String name)方法

代码二是通过继承ClassLoader这个顶层类加载器实现,findClass(String name) 这个方法需要自己实现,比较麻烦,上面代码二的方法还是有点问题的,


一般通过代码一的方式实现就行了,URLClassLoader内部实现还是完善的.

你可能感兴趣的:(java,ClassLoader)