Java语言是一种先天具备动态性的语言,之所以具备动态性正是因为Java类装载器的存在。这会给我们开发带来革命性的变革,因为我们有可能开发出有弹性、易扩展的程序。从而大大增强我们程序的可维护性。按载入条件分为预先载入与按需载入。
1.通常基础类库需要预先载入。(常驻内存)
2.自定义类库需要按需载入。(使用时载入,使用完毕时由垃圾收集器负责释放)
类装载器运行模式分为两种,如下图:
1.使用new关键字来隐式加载,首先来看一个例子:直接上代码,很简单的三个类。
但是我们如果需要看类加载的详细内容,我们就要用到这条命令:java -verbose:class Main
看看上图是不是首先载入的Java的基础类库,看最后几行,首先加载Main,接下来实例化A类的时候会加载A,调用a.print()的时候打印了Using class A,然后加载B类,执行B中的方法。
2.使用Class.forName()方法载入类,这个做过J2EE开发的应该知道,在数据库连接加载驱动的时候都可以这么加载。还是看一个简单的例子:
详细观察一下最后几行载入的顺序,看看是否跟我们程序执行的是一样的呢?
此处有一个结论:Java类装载器会按照继承体系从上至下的依次载入类,直到所有的祖先类都载入(上例中是接口),才轮到自己;相反,在Java类对象实例被收集释放时,顺序与载入相反。由此,我们也能看出,Java类的继承体系不宜过长,因为那样会使类的载入与释放的性能受到影响。
3.直接使用类装载器ClassLoader,例子是上一个例子的改版,只是修改了Main.java,其他三个类不变。
怎么样,Java语言够动态吧。
转载来源 www.boobooke.com/bbs->J2EE 专区->蓝山作品—Java背后的秘密(汇总)
public class A { public void print() { System.out.println("Using class A"); } }
public class B { public void print() { System.out.println("Using class B"); } }
public class Main { public static void main(String[] args) { A a = new A(); a.print(); B b = new B(); b.print(); } }运行结果如下:
看看上图是不是首先载入的Java的基础类库,看最后几行,首先加载Main,接下来实例化A类的时候会加载A,调用a.print()的时候打印了Using class A,然后加载B类,执行B中的方法。
2.使用Class.forName()方法载入类,这个做过J2EE开发的应该知道,在数据库连接加载驱动的时候都可以这么加载。还是看一个简单的例子:
public interface Office { void start(); }
public class Word implements Office { public void start() { System.out.println("Word start"); } }
public class Excel implements Office { public void start() { System.out.println("Excel start"); } }
public class Main { public static void main(String[] args) throws Exception{ Class c = Class.forName(args[0]); Object o = c.newInstance(); Office office = (Office) o; office.start(); } }继续看一下加载的详细内容:
详细观察一下最后几行载入的顺序,看看是否跟我们程序执行的是一样的呢?
此处有一个结论:Java类装载器会按照继承体系从上至下的依次载入类,直到所有的祖先类都载入(上例中是接口),才轮到自己;相反,在Java类对象实例被收集释放时,顺序与载入相反。由此,我们也能看出,Java类的继承体系不宜过长,因为那样会使类的载入与释放的性能受到影响。
3.直接使用类装载器ClassLoader,例子是上一个例子的改版,只是修改了Main.java,其他三个类不变。
public class Main { public static void main(String[] args) throws Exception { System.out.println("begin load"); // Main main = new Main(); // ClassLoader loader = main.getClass().getClassLoader(); ClassLoader loader = Main.class.getClassLoader(); Class c = loader.loadClass(args[0]); System.out.println("begin init"); Object o = c.newInstance(); Office office = (Office) o; office.start(); } }首先获得ClassLoader的实例,有两种方法,上面注释的为一种,放开的为另一种。然后调用loadClass()方法。运行一下,看下效果:
怎么样,Java语言够动态吧。
转载来源 www.boobooke.com/bbs->J2EE 专区->蓝山作品—Java背后的秘密(汇总)