`
lixiao
  • 浏览: 14265 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

[笔记]Class.forName 时static代码的运行

    博客分类:
  • java
阅读更多

Java 类的装载过程
查看Java load class 的信息:
java -verbose:class MyClass

 

测试代码

public class MyTest{
    public static void main(String args[]) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        Class cla = Class
                .forName("A", true, CRCCheckSum.class.getClassLoader());
        System.out.println("After Class.forName(). Before class.newInstance()");
        cla.newInstance();
        new A();
        Class.forName("A"); // find class A ,skip load
    }
}
class A {
    public A() {
        System.out.println("public A() Constructor");
    }

    static {
         System.out.println("static Code");
    }

    { System.out.println("non static Code");
    }
}

 输出:

static Code
After Class.forName(). Before class.newInstance()
non static Code
public A() Constructor
non static Code
public A() Constructor

 

我的理解:

让Java加载类有三种情况,

1.直接new ,如:new MyClass();

2.Class.forName, 如:Class.forName ("org.gjt.mm.mysql .Driver")

3.定义ClassLoader,用其loadClass方法.

 

JVM加载一个未加载过的类分几步:

a.装载 b.连接 c.初始化 d.实例化

 

对于1.直接就abcd连着执行了

对于2.其有两个方法可以选择是ab,还是abc.

对于3.如果改变实现似乎可以控制到a,和ab.

 

1就不分析了.

 

对于2

有两个方法:

1)Class.forName(String className)

2)Class.forName(forName (String  name, boolean initialize, ClassLoader  loader)

后者的initialize参数是指名,是否需要在装载连接完毕类后,进行初始化的工作.也就是执行static代码等.

如果Class.forName("MyClass") 则相当于:Class.forName("MyClass",true,this.getClass.getClassLoder());

这个也就是为什么要用

Class.forName("com.mysql.jdbc.Driver" ); 来注册driver

因为com.mysql.jdbc.Driver中有这样的代码:

public class Driver extends NonRegisteringDriver
{
    public Driver() throws SQLException
    { }

    static


    {
        try {
            DriverManager.registerDriver(new Driver());


        }
        catch(SQLException E) {
            throw new RuntimeException("Can't register driver!");
}}}

 这样调用,由于在Class.forName进行加载的时候会自动执行初始化,也就是想DriverManager注册自己.

 所以就不必再用newInstance()来生成一个实例.

 

对于3.有这样两个方法

ClassLoader.loadClass(String className);

protected ClassLoader.loadClass(String className,boolean resolve);

关于resolve的行为还不太懂,改天继续写.

 

classLoder 层次:

  bootstrap classloader
                 |
  extension classloader
                 |
  system classloader

 

获得bootstrap classLoader加载哪些内容:

       URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
          System.out.println(urls[i].toString());
        }

 

获得SystemClassLoader(): ClassLoader.getSystemClassLoader()

获得ExtensionClassLoader():ClassLoader.getSystem.ClassLoader().getParent();

 

参考文章:

http://www.iteye.com/topic/25053

http://www.iteye.com/topic/189897

http://www.iteye.com/topic/11003

http://www.iteye.com/topic/12084

http://www.iteye.com/topic/68170

http://www.iteye.com/topic/70217

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics