20名前空間のクラスローダと実際の分析を徹底的に理解

名前空間のクラスローダと実際の分析を徹底的に理解

重要な注意名前空間:[主に例IVおよびVを参照します]

  1. ロードサブクラスは、クラスがクラスをロードするために、親クラスローダへのアクセスを得ることができますロード。
  2. クラスローダは、子ロードされたクラスにアクセスすることはできません親クラスローダがロードされます。
  • 例1:

    • public class MyCat {
          public MyCat(){
              System.out.println("MyCat is loaded by:"+this.getClass().getClassLoader());
          }
      }
      
      public class MySample {
         public MySample() {
            System.out.println("MySample is loaded by :" +this.getClass().getClassLoader());
            new MyCat();  //【重要】
         }
      }
      
      public class MyTest17_1 {
          public static void main(String[] args) throws Exception {
              //MyTest16是一个自定义的类加载,在15+16章节中可以找到
              MyTest16 loader1 = new MyTest16("loader1");
              loader1.setPath("C:\\Users\\admin\\Desktop\\");
              Class<?> clazz = loader1.loadClass("Jvm.MySample");  //先加载
              System.out.println("class : " + clazz.hashCode());
              //如果注释掉该行,那么并不会实例化MySample对象,即MySample构造方法不会被调用
              //因此不会实例化MyCat对象,即没有对Mycat进行主动使用,这里就不会加载MyCat Class
              Object object = clazz.newInstance();  //再创建实例
          }
      }
      
      运行结果:
            findClass invoked:Jvm.MySample
            class loader name:loader1
            class : 856419764
            MySample is loaded by :[loader1]
            ---------------------------------
            findClass invoked:Jvm.MyCat
            class loader name:loader1
            MyCat is loaded by:[loader1]
      
      • 分析の結果:[前提:、MYSAMPLE、MyCatのクラスファイルを削除し、デスクトップJVMにフォルダをコピー]

        • 分割ラインの理解に先立ち、

        • 行を分割した後、インスタンスが作成されるときでMYSAMPLEでコール新しいMyCat()、それはMyCatは、この時間をクラスファイルをロードするだろう、ファイルをロードするMyTest16カスタムクラスローダーがまだある、あなたが持っています。

          findClass invoked:Jvm.MyCat
          class loader name:loader1
          MyCat is loaded by:[loader1]
          
  • 例2:

    • コードまたはコード上で、[前提:削除しないファイルが出てMYSAMPLEん、削除MyCatクラスファイル]
      • MYSAMPLEをロードするためにこの時点で、あなたはファイルを見つけることができ、対応するクラスファイルで見つかった、それはシステムクラスローダによってロードされます。私たちがMYSAMPLEに行ってきまし負荷Mycat時間、ローダーの使用に起因するとMYSAMPLEは同じですシステムクラスローダでなく、負荷未満であるので、我々は、フォルダの外にMycat.classファイルを削除:NoClassDefFoundErrorが
    运行结果:
       class : 1761291320
       MySample is loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
       Exception in thread "main" java.lang.NoClassDefFoundError: Jvm/MyCat
          at Jvm.MySample.<init>(MySample.java:6)
          ......
    
  • 三つの例:

    • コードまたは上記のコード、[前提:MYSAMPLE内のファイルを削除しませんが、唯一の削除MyCatクラスファイル]

      • クラスファイルうち該当するフォルダが存在しないためMYSAMPLEについては、カスタムクラスは、負荷によってロード。

      • MyCatそれについて、MyCatは、負荷にMYSAMPLE(MyTest16、すなわちloader1)をロードするクラスローダによって使用されているこの時間は、機構による委託両親とは知っている可能性があり、loader1は、それゆえ、MyCatをロードするために、その父を委託し、最終的なMyCatは、システムクラスローダによってロードされます。

        运行结果:
           findClass invoked:Jvm.MySample
           class loader name:loader1
           class : 783286238
           MySample is loaded by :[loader1]
           MyCat is loaded by:sun.misc.Launcher$AppClassLoader@18b4aac2
        
  • 4つの例:

    • ローダーは、親クラスローダがロードされて見ることができるサブクラスによってロードされた、しかし、親クラスローダによって目に見えないサブクラスローダがロードされてロードされました。

      • すべてが変更されますが、MyCatクラスのSystem.out.println(「MyCatから:」+ MySample.class)に追加の行を追加していません。[MySample.classフォルダアウトもファイルの削除]。

      • 問題なく結果を操作する最初の5行:(+「MyCatから」のSystem.out.printlnの実装 ; MySample.class) この一ため、クラスローダのは(:AppClassLoader MyCatをロードするクラスローダ)を使用します、**今回、AppClassLoaderはローダーですMySample.classファイルを見つける(カスタムクラスローダ)親クラスローダが、彼は**、子ローダーロードしたクラス(コンテンツ)を見ることができないので、エラー、私は、クラスファイルを見つけることができません

        public class MyCat {
            public MyCat(){
                System.out.println("MyCat is loaded by:"+this.getClass().getClassLoader());
                System.out.println("from MyCat : " +MySample.class);  
            }
        }
        
        运行结果:
              findClass invoked:Jvm.MySample
              class loader name:loader1
              class : 783286238
              MySample is loaded by :[loader1]
              MyCat is loaded by:sun.misc.Launcher$AppClassLoader@18b4aac2
              Exception in thread "main" java.lang.NoClassDefFoundError: Jvm/MySample
              ......
              Caused by: java.lang.ClassNotFoundException: Jvm.MySample
        
  • 5の実施例:[5つのインスタンスを有するフォー例コントラスト]

    • 以上のラインでMYSAMPLE給与:System.out.printlnは( "MyCatから:" + MyCat.class); [削除された]アウトMySample.classで

      • 成功しMyCatから印刷実行中の最後の行の主な結果:クラスJvm.MyCat; MYSAMPLE、MyCatは、カスタムクラスローダによってロードされているため、親クラスローダによってロードされ、そのクラスのサブクラスによってロードされた名前空間には、それらをロードあなたは、ロードされた親クラスローダによってオブジェクトにアクセスすることができます。

        public class MySample {
            public MySample() {
                System.out.println("MySample is loaded by :" +this.getClass().getClassLoader());
                new MyCat();  //【重要】
                System.out.println("from MyCat : " +MyCat.class);
            }
        }
        
        public class MyCat {
            public MyCat(){
                System.out.println("MyCat is loaded by:"+this.getClass().getClassLoader());
            }
        }
        
        运行结果:
           findClass invoked:Jvm.MySample
           class loader name:loader1
           class : 783286238
           MySample is loaded by :[loader1]
           MyCat is loaded by:sun.misc.Launcher$AppClassLoader@18b4aac2
           from MyCat : class Jvm.MyCat
        
公開された25元の記事 ウォンの賞賛0 ビュー1453

おすすめ

転載: blog.csdn.net/qq_40574305/article/details/104793438
おすすめ