《Java深度历险》读书笔记一

1.类加载器(ClassLoader)

  Class.forName()有两种用法,一个是:public static Class<?> forName(String className) throws ClassNotFoundException
  他等同于Class.forName(className,true,currentClassLoader);

  另一种为:public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException
  下面分别说说这三种参数的意义:
  name,要加载的类名
  initialize,是否必须初始化类
  loader,类加载器。手动调用时可以使用this.getClass().getClassLoader();

  下面用代码说明:
public class Word implements Office {
    static {
        System.out.println("Word's Static Initialize");
    }
    public void start() {
        System.out.println("Word");
    }
}
interface Office {
    public void start();
}

 
public class Main {
    public static void main(String[] args) throws Exception {
        if (args[0] != null) {
            Outlook off = new Outlook();
            System.out.println("类别准备载入");
            Class c = Class.forName(args[0],false,off.getClass().getClassLoader());
            System.out.println("类别准备实例化");
            Object o = c.newInstance();
            Office office = (Office)o;
            office.start();
        }
    }
}

注意红字部分,如果initialize为false,执行java -verbose Main Word
日志输出为:
[Loaded Office from file:/E:/MyJava/]
[Loaded Outlook from file:/E:/MyJava/]
类别准备载入
[Loaded Word from file:/E:/MyJava/]
类别准备实例化
Word's Static Initialize
Word

如果initialize为true
[Loaded Main from file:/E:/MyJava/]
[Loaded Office from file:/E:/MyJava/]
[Loaded Outlook from file:/E:/MyJava/]
类别准备载入
[Loaded Word from file:/E:/MyJava/]
Word's Static Initialize
类别准备实例化
Word

看出区别来了吧,如果为true,当Word第一被加载的时候,Word就被初始化了(静态块中的内容被调用了),否则加载时不被初始化,只有等到实例化的时候再初始化,注意静态块是先于构造函数调用的。

2.类加载器加载顺序
  如果再命令行输入:java xxx,执行顺序为:
  a.找到JRE
  b.找到jvm.dll
  c.启动JVM,并进行初始化
  d.产生BootstrapLoader
  e.由BootstrapLoader载入ExtClassLoader
  f.由BootstrapLoader载入AppClassLoader
  g.由AppClassLoader载入xxx

  这里比较有意思的是:AppClassLoader由BootstrapLoader载入,但是当调用他的getParent()方法时,却指向ExtClassLoader
  因为ExtClassLoader和AppClassLoader都由BootstrapLoader(由C++编写)载入,所以调用他们的getLoader()方法时,返回null,BootstrapLoader不是Java内在类

3.AppClassLoader和ExtClassLoader都是由URLClassLoader继承而来的,所以要设定他们的URL。
  AppClassLoader的URL是从系统属性“java.class.path”得到的。而java.class.path则是由执行java.exe是-cp或者-classpath(优先级高)或由CLASSPATH环境变量决定的。
  所以默认他们都是从“.”,即当前目录开始查找。
  ExtClassLoader是从“java.ext.dirs”系统属性中查找,即JRE所在位置下的"lib"ext子目录
  我用System.out.println(System.getProperty("java.ext.dirs"))输出为:
  C:"Java"jdk1.6.0_02"jre"lib"ext;C:"WINDOWS"Sun"Java"lib"ext

  可以通过java -Djava.ext.dirs=c:"winnit Test来改变

  而BootstrapLoader的搜索路径由"sun.boot.class.path"来确,却不能用java -D来改变。

posted on 2008-09-27 18:05  angelox  阅读(731)  评论(0编辑  收藏  举报

导航