類載入器[4]由不同ClassLoader物件載入的同名類屬於不同類
阿新 • • 發佈:2019-01-01
由不同ClassLoader物件載入的同名類屬於不同的型別,不能相互轉化和相容。
新建一個工程NotSameClass。將如下程式碼,一份放入NoSameClass工程原始碼目錄下,一份編譯成.class放入D:\temp目錄下
執行如下程式碼,使用不同的類載入器載入同一個類(原始碼都一樣,不過一個來自bin目下的.class,一個來自D:\temp下的.class)
Java Code
package com.bjsxt.test; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; publicclass Test { publicstaticvoid main(String[] args) { //先用應用類載入器載入HelloLoader HelloLoader object1=new HelloLoader(); System.out.println(object1.getClass().getClassLoader()); ClassLoader cl = ClassLoader.getSystemClassLoader(); try { byte[] classBytes = loadClassBytes("com.bjsxt.test.HelloLoader"); Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class defineClassMethod.setAccessible(true); defineClassMethod.invoke(cl.getParent(), classBytes, 0, classBytes.length); Class<?> clazz = cl.getParent().loadClass("com.bjsxt.test.HelloLoader"); System.out.println(clazz.getClassLoader()); //兩個不同類的物件強制型別轉換 object1=(HelloLoader)clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); }catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } /** * 將包名中的.替換成路徑分隔符,從D:/temp/目錄下查詢這個檔案,如果存在的話,將其讀取到位元組陣列 * @param name * @return */publicstaticbyte[] loadClassBytes(java.lang.String name) { String path="D:/temp/"+name.replace(".", "/")+".class"; InputStream is=null; ByteArrayOutputStream baos=null; try { is=new FileInputStream(path); baos=new ByteArrayOutputStream(); byte[] buffer=newbyte[1024]; int ret=0; while((ret=is.read(buffer))!=-1){ baos.write(buffer, 0, ret); } return baos.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(is!=null) is.close(); if(baos!=null) baos.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } } |
並且,即便是同一類 類載入器,不同的物件加載出來的類也不是同一個類。