您的位置:首页 > 编程语言

static 是在什么时候加载的(代码验证)

2017-02-08 10:03 295 查看
               static代码块到底是在类被加载,还是初始化的时候执行的呢?
         首先新建一个A.Class:

     package cn.proxy;

public class A {   
static{
System.out.println("static 静态代码块");
}  
public A(){
System.out.println("构造器");
}



     再写一个测试类:

    public class ATest {

   public static void main(String[] args){

   A a=new A();

}

}

结果:

static 静态代码块

构造器

由此可见  static代码块会在类实例化的时候执行,知道这,我们就可以把类实例化之前要做的事情放在静态代码块中来执行了.

然后修改ATest 如下:

  try {

Class.forName("cn.proxy.A");
 
} catch (ClassNotFoundException e) {

e.printStackTrace();
}

结果:

static 静态代码块

现在我们来看看Class.forName的含义:在api中如下定义:forName

返回与带有给定字符串名的类或接口相关联的
Class
对象。调用此方法等效于:

Class.forName(className, true, currentLoader)


其中
currentLoader
表示当前类的定义类加载器。

例如,以下代码片段返回命名为
java.lang.Thread
的类的运行时
Class
描述符。

Class t = Class.forName("java.lang.Thread")


调用 forName("X") 将导致命名为 X 的类被初始化。

最后一句 类被初始化,也就是说static是在类被初始化的时候执行的.

再来看看类被加载的时候执行的情况:

修改ATest 如下:

   try {              

                       //java.security.SecureClassLoader类是ClassLoader类的子类.
Class<?> clazz= Class.forName("java.security.SecureClassLoader");

                      //SecureClassLoader类中的构造器不是public的,所有要设置外部被访问
Constructor<SecureClassLoader> c=(Constructor<SecureClassLoader>) clazz.getDeclaredConstructor();
c.setAccessible(true);

                     //实例化SecureClassLoader 
SecureClassLoader sc=c.newInstance();

                    //取得ClassLoader 对象并且加载A对象

sc.getParent().loadClass("cn.proxy.A");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

结果

为空,什么都不输出

若sc.getParent().loadClass("cn.proxy.A").newInstance();

结果:

static 静态代码块

构造器

综上所述static是在类被初始化的时候执行的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: