java类加载机制的一些自我总结

来源:互联网 发布:电脑无法上淘宝 编辑:程序博客网 时间:2024/06/06 09:05

(首先声明:这些文章都是自己的学习总结 写出来只为梳理自己的知识框架 也为日后巩固自身的java基础之用 ,也希望能帮到爱好java的朋友,能力有限 有错的地方欢迎大家提出来)

由于本人学java基础是在linux环境下,所以这里也是配合Linux环境讲解的

启动类加载器:.bootstrap class loader  加载Java的核心类,放在/opt/jdk1.7.0_45/jre/lib目录下 全部是Java.开头的jar包
扩展类加载器:.extensiable class loader 加载Java的扩展类  放在/opt/jdk1.7.0_45/jre/lib/ext目录下 全部是Javax.开头的jar包
系统类加载器:.system class loader(加载自己写的类) 路径指令CLASSPATH下的字节码文件(编译生成的.class文件,它保存类的信息)
网络类加载器:.network class loader
自己写的类若要加载成功,必须经过双亲委托机制,即:系统类加载器在加载自己写的类的字节码文件之前,先检查上两层加载器中加载的类中是否有类名相同的类,若有则不重复加载,若没有本层才能加载成功
验证如下:
  1.在bin目录下把自己写的类打成jar包:jar cvf hello.jar com
  2.删掉com 则字节码文件就不存在了:rm -r com
  3.直接运行:java com.briup.ch01.helloJava  //此时找不到要加载的类
  4.将这个类放入扩展类目录下:sudo mv bin/hello.jar /opt/jdk1.7.0_45/jre/lib/ext/  //移动到系统目录下而不是家目录下需要超级用户
  5.再运行这个类:java com.briup.ch01.helloJava //此时可以运行成功


注:将自己写的类放入核心(或扩展类)目录下有一定的坏处:如果忘记自己放进核心类或扩展类目录中的类,下一次又写了一个类名相同的类,无论怎么改都不会有变化 
  6.所以需要删掉:sudo rm -r hello.jar


这种机制导致一个写程序时需要注意的地方:若有两个类 class A  class B 若A的加载器级别比B高,类A调用类B A永远找不到B 因为类A只会找加载器级别与自己相同或者比自己高的类,不会去找比自己低的类
验证如下:
   1.写两个类A、B A调用B
  package com.briup.ch01;
  public class A
  {
     public static void main(String[]args)
     {
         B.method();
      }
  }
  
  package com.briup.ch01;
  public class B
  {
     public static void method()
     {
        System.out.println("A call B");
      }
   }


  2.正常情况下肯定可以调用成功:javac -d bin src/A.java src/B.java  
                                java -cp bin com.briup.ch01.A
  3.若将A打成jar包放入扩展类目录下:rm -r com/briup/ch01/B.class  //将B.class删除
                                    jar cvf A.jar com             //将A打成jar包
                                    sudo mv A.jar /opt/jdk1.7.0_45/jre/lib/ext/   //将A的jar包放入扩展类目录
                                    rm bin/com/briup/ch01/A.class    //将A.class删除
  4.重新运行A则会出现类无法找到的异常:java com.briup.ch01.A  


0 0
原创粉丝点击