20 네임 스페이스의 클래스 로더와 실제 분석에 대한 철저한 이해

네임 스페이스의 클래스 로더와 실제 분석에 대한 철저한 이해

중요 네임 스페이스 : 주로 실시 예 IV 및 V를 참조한다]

  1. 로드 서브 클래스는 클래스가 클래스의로드를 상위 클래스 로더에 액세스 할 수 있습니다로드;
  2. 부모 클래스 로더로드 클래스 로더는 아이에게하지 액세스 클래스를로드 할 수 있습니다.
  • 예 하나 :

    • 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은 부하로 (MyTest16, 즉 loader1) 부하 mysample이에 클래스 로더에 의해 사용되는 메커니즘에 의해이 시간, 부모와 위탁 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
        
  • 네 예 :

    • 서브 클래스에 의해로드 로더는 부모 클래스 로더는 부모 클래스 로더에 의해, 그러나,로드 참조 눈에 보이지 않는 서브 클래스 로더가로드로드 할 수 있습니다.

      • 모든 변경,하지만 MyCat 클래스에서 System.out.println ( "MyCat에서"+ MySample.class)에 추가로 줄을 추가하지 않습니다 [MySample.class 폴더 밖으로도 삭제 파일].

      • 문제없이 결과를 동작 처음 다섯 개 라인 에서 System.out.println의 구현 ( "MyCat에서"+ 때 MySample.class) 때문에 클래스 로더,이 사용된다 (로드 MyCat에 클래스 로더 : AppClassLoader) **이 시간의 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
        
  • 다섯 가지의 예 : 다섯 개 개의 인스턴스와 대조 예]

    • 더 라인 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