1、ClassLoaderクラスローダー紹介
Java環境変数でのシステム提供:JVMプロセスの起動時にクラスパスを、このプロパティの役割は主に、つまり、あなたはその後、内部JVMでのパスのクラスローダを指定したクラスにロードすることができ、クラスローダのパスを定義していますクラスローダは、クラスのソースを見つけるための手段を見つけることです。
システムクラスローダ
あなたは今、クラスローダを取得するためには、それはクラスローダを介して取得しなければならず、オブジェクトClassLoaderクラスを得るために、あなたがのルートを使用しなければならないと言うなら、クラスのクラスの実装方法[反映]:取得した公開クラスローダのgetClassLoader()が、クラスローダ後、その親クラスのClassLoaderクラスオブジェクトを取得し続けることができる:パブリック最終的なクラスローダのgetParentを();
・例:クラスローダを観察
1 クラスメッセージ{ 2 } 3。 パブリック クラスJavaAPIDemo { 4。 公共 静的 ボイドメイン(文字列[]引数){ 5。 メッセージclazzクラス= <?>。クラス、 図6 のSystem.out.println(clazz.getClassLoader()); // 現在のクラスローダを取得します 7。 のSystem.out.println(clazz.getClassLoader()のgetParent()); // 親クラスローダを取得します 。8 のSystem.out.println(clazz.getClassLoader()のgetParent()のgetParent(.. )); // 取得祖父母クラスローダ 9 } 10 } 11 / * 12 jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc 13 jdk.internal.loader.ClassLoaders$PlatformClassLoader@1e643faf 14 ヌル 15 * /
[] [PlatformClassLoader]クラスローダと、以前のバージョンとJDK1.8ローダに設けられたそれ以降のバージョンとJDK1.10 JDK1.9 JDK1.8からJDKにインストールされ、[] ExtClassLoader内部に設けられていますディレクトリが別のextディレクトリを提供し、開発者は、[] * .jarファイルをこのディレクトリにコピーされていることができますので、直接実行することができますが、このような治療の開発は、それは眉をひそめた最初の時間は安全ではありませんそうJDK1.9からは完全に廃止し、そして順に、システムローダとアプリケーションクラスローダとの間で設計のバランスを維持するために、プラットフォームのクラスローダを提供します。
あなたが得るときにクラスローダは、リフレクションベースの処理負荷のクラスローダを使用して実装することができます。
2、カスタム処理クラスローダ
セルフオーダーシステムのすべてのクラスローダの最後にロードしたカスタムクラスローダ:明らかにクラスローダ機能の後は、カスタムクラスローダを実装するが、一つのことを覚えておく必要があり、その必要性に応じてすることができます。クラスのためのシステムクラスローダは、CLASSPATHは、パスを見つけるにロードされ、そして、彼らは自己定義されたクラスローダを持っている場合は、開発者のローディング位置で任意のクラスに割り当てることができます。
①フリープログラムのクラスを記述するために、このクラスは、ディスク上に保存されます。
1 import java.io.*; 2 3 public class MufasaClassLoader extends ClassLoader { 4 private static final String MESSAGE_CLASS_PATH="D:"+ File.separator+"Message.class"; 5 /** 6 * 进行指定类的加载 7 * @param className 类的完整名称【包.类】 8 * @return 返回一个指定类的class对象 9 * @throws Exception 如果类文件不存在则无法加载 10 */ 11 public Class<?> loadData(String className)throws Exception{ 12 byte[] data=this.loadClassData();//读取二进制数据文件 13 if(data!=null){//读取到数据 14 return super.defineClass(className,data,0,data.length); 15 } 16 return null; 17 18 } 19 private byte[] loadClassData()throws Exception{//通过文件进行类的加载 20 InputStream input=null; 21 ByteArrayOutputStream bos=null;//将数据加载到内存之中 22 byte[] data=null; 23 try{ 24 bos=new ByteArrayOutputStream();//实例化内存流 25 input=new FileInputStream(new File(MESSAGE_CLASS_PATH));//文件流加载 26 // byte[] data=new byte[1024];//进行读取方式① 27 input.transferTo(bos);//读取数据方式② 28 data= bos.toByteArray();//将所有读取到的字节数组取出 29 }catch (Exception e){ 30 31 }finally { 32 if(input!=null){ 33 input.close(); 34 } 35 if(bos!=null){ 36 bos.close(); 37 } 38 } 39 return data; 40 } 41 }
④编写测试类实现类加载控制;
1 package cn.mufasa.demo; 2 import cn.mufasa.util.MufasaClassLoader; 3 import java.lang.reflect.Method; 4 5 public class JavaAPIDemo1 { 6 public static void main(String[] args) throws Exception { 7 MufasaClassLoader classLoader=new MufasaClassLoader(); 8 Class<?> cls=classLoader.loadData("cn.mufasa.util.Message");//进行类的加载 9 System.out.println(cls); 10 Object obj=cls.getDeclaredConstructor().newInstance(); 11 Method method=cls.getDeclaredMethod("send"); 12 method.invoke(obj); 13 } 14 } 15 /* 16 读取到数据 17 class cn.mufasa.util.Message 18 www.cnblogs.com 19 */
如果在以后结合网络开发的话,就可以通过一个远程的服务器来确定类的功能。
⑤观察当前的Message类的加载器的情况
package cn.mufasa.demo; import cn.mufasa.util.MufasaClassLoader; import java.lang.reflect.Method; public class JavaAPIDemo1 { public static void main(String[] args) throws Exception { MufasaClassLoader classLoader=new MufasaClassLoader(); Class<?> cls=classLoader.loadData("cn.mufasa.util.Message");//进行类的加载 // System.out.println(cls); System.out.println(cls.getClassLoader());//获取当前类的加载器 System.out.println(cls.getClassLoader().getParent());//获取父类加载器 System.out.println(cls.getClassLoader().getParent().getParent());//获取祖父类加载器 } } /* cn.mufasa.util.MufasaClassLoader@668bc3d5 jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc jdk.internal.loader.ClassLoaders$PlatformClassLoader@3fb6a447 */
如果说你先在定义了一个类,这个类的名称定义为:java.lang.String,并且利用了自定义类加载器进行加载处理,这个类将不会被加载,原因:Java之中针对于类加载器提供有双亲加载机制,如果现在要加载的类是由系统提供的类则会由系统类进行加载,如果现在开发者定义的类与系统类定义的名称相同,那么【为了保证系统的安全性】绝对不会加载。