2 zyf4005 zyf4005 于 2016.05.07 08:23 提问

关于java中加载和初始化的疑问?各位帮忙分析下

public class ExA {

private static ExA a = new ExA();
static {
    System.out.println("父类--静态代码块");
}

 public ExA() {
    System.out.println("父类--构造函数");
}

{
    System.out.println("父类--非静态代码块");
}

public static void main(String[] args) {
    new ExB();
}

}
程序执行时先找到程序入口即main函数,接着加载和初始化main函数所在的类即ExA,那么第一句就是private static ExA a = new ExA();那么执行这句代码的时候发生了什么?我知道的是先把a设置为null,然后才去赋值为new ExA();关键是new ExA()(第一次创建对象)的时候按道理不是会触发ExA类的加载和初始化吗?但这句代码就在ExA类初始化的第一行,难道要跳过去初始化static { System.out.println("父类--静态代码块"); }吗?还是有别的理解?
第二个疑问:是不是当要首次创建一个类的对象时,前提条件是这个类必须先加载和初始化都完成后才能首次创建类的对象?还是说只要这个类加载了虽然没有初始化就可以创建类的对象了?

class ExB extends ExA {

private static ExB b = new ExB();
static {
    System.out.println("子类--静态代码块");
}
{
    System.out.println("子类--非静态代码块");
}

public ExB() {
    System.out.println("子类--构造函数");
}

}

5个回答

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.05.09 12:42
已采纳

首先,你注释掉这两个类中所有的静态代码块,执行代码,可以看到类的实例化过程中,父类、子类非静态代码库、构造函数调用的顺序了。
非静态代码块和构造函数,都是用来实例化类时初始化类的成员变量的,即init(){ 非静态代码块+构造函数},而且非静态代码块总是在构造函数之前调用的。

 父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数

其次,静态代码块,在这个类第一次被调用或实例化的时候就会被执行。 静态代码块只会执行一次,一般会用来初始化一些值,并且在所有对象中全局共享。比如:你注释掉所有代码,如下:直接执行空的main函数时,ExA类被加载时就会执行静态代码块:

 public class ExA {

    static {
        System.out.println("父类--静态代码块");
    }


    public static void main(String[] args) {

    }

}

因为你是ExA中的main方法,加载这个类时就会执行这个类的静态代码块。
你的第二个问题,我们在使用一个类之前,它必须经过装载,连接,初始化这样的过程。然后我们才能使用new操作实例化创建对象,它的初始化就是执行类的静态代码块,完成全局属性的设置。我认为构造函数则是实例化创建对象时调用的,跟类的初始化不是一个概念的。
参考链接:blog.csdn.net/moreevan/article/details/6968718

zyf4005
zyf4005 那么我的疑问是你既然说“我们在使用一个类之前,它必须经过装载,连接,初始化这样的过程。然后我们才能使用new操作实例化创建对象,”那么代码的第一句private static ExA a = new ExA();这时候类ExA还没有加载和初始化完成呢,那岂不是就无法new ExA()了吗?
大约 2 年之前 回复
niaonao
niaonao   Rxr 2016.05.07 11:29

在main 开始之前先执行一次 类加载
(且只执行一次,执行的是相关的静态代码块或函数)

然后找main 入口开始执行

yonghuwangwei
yonghuwangwei   2016.05.09 11:31

静态代码块或函数是由java虚拟机执行的,且只在加载到内存时执行一次,先执行private static ExA a = new ExA();,因为有new所以转而执行非静态代码
和构造方法(应为此时是同一个类的初始化过程中,所以new的时候不会执行静态代码,静态代码由new完之后的虚拟机执行,同时静态代码是公共的),接着
执行静态代码,接着new一个给子类,所以执行非静态代码和构造方法。

zyf4005
zyf4005 本来执行private static ExA a = new ExA();的时候因为是首次new,所以会导致类ExA的加载和初始化。因为此时有main导致的类的加载和初始化。这两个初始化是一个类,所以才去执行了非静态代码。那你的意思可以理解为在类的加载和初始化过程中就可以创建对象,没有要求说:类必须加载和初始化完成后才能创建对象是吧?
大约 2 年之前 回复
havedream_one
havedream_one   2016.05.09 19:49
public class Test20160509 {
    public static int k = 5;
    public static Test20160509 t1 = new Test20160509("t1");
    public static Test20160509 t2 = new Test20160509("t2");
    public static String s = "abcd";
    public static int i = print("i");
    public static int n = 99;

    public int j = print("j");

    {
        print("非静态构造块");
    }

    static {
        print("静态块");
    }

    public Test20160509(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n + "   str=" + s + "  t1=" + t1 + "   t2=" + t2);
        ++i;
        ++n;
    }

    private static int print(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n + "   str=" + s + "  t1=" + t1 + "   t2=" + t2);
        ++n;
        return ++i;
    }

    public static void main(String[] args) {
        Test20160509 t = new Test20160509("init");
        Test20160509 t2 = new Test20160509("init2");

    }

}

图片说明

havedream_one
havedream_one   2016.05.09 19:49
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
求助各位高手,帮忙做下,谢谢了
由计算机“想”一个四位数,请人猜出这个四位数是多少。人输入四位数字后,计算机首先判断这四位数字有几位是猜对了,并且在对的数字中又有几位位置也是对的,将结果显示出来,给人以提示,请人再猜,直到人猜出计算机所想的四位数是多少时为止。 
Java中为什么long能自动转换成float类型
刷题时候看到一个float和long相互转换的问题,float向long转换的时候不会报错,一个4个字节一个8个字节,通过baidu找到了答案。 下面转载自http://blog.csdn.net/shanshan1yi/article/details/48477119 /****************************************************分割线******
数位和
前言牛客网PAT乙级训练1018题目描述 把一个整数的各位累加,NowCoder称它为“数位和”。例如正整数123456的数位和是1+2+3+4+5+6=21。现在,请你帮忙计算一个整数n在r进制下的数位和,并用相应的进制输出结果。 输入描述 输入有多组数据。 每组数据包含两个正整数n (1≤n≤2147483647)和r (2≤n≤16)。 输出描述 对应每一组数据,输出十进制正
帮忙选个号手机号码末四位:4739、3636,2577,8968,1717,2424,8886,5678,4619,5151,6226,1212,4321,2157,3445,觉得哪个好?
帮忙选个号手机号码末四位:4739、3636,2577,8968,1717,2424,8886,5678,                                               4619,5151,6226,1212,4321,2157,3445,觉得哪个好? 刚才帮忙选号的注意了,现在公布答案。 非常感谢你的参与,这只是个游戏而已,请你自己对号入座看答案[呲牙]放松下心
这道java关于static和类加载初始化的面试题(很经典)
package com.yq; public class TestA { { System.out.println("hello A"); } public TestA(){ System.out.println("TestA constructor!"); } static{ System.out.println("TestA static"); } }
Java类加载器:静态变量初始化
先看两个例子: package wh; class Singleton{ public static Singleton singleton = new Singleton(); public static int a; public static int b = 0; private Singleton(){ a++; b++; } public static
帮忙各位
小弟跪求PHP和MYSQL安装包和安装视频
深入java虚拟机加载初始化
深入研究java加载初始化............
Netty------对于Netty的十一个疑问
1.Netty 是什么?   Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。   2.使用 Netty 能够做什么? 开发异步、非阻塞的 TCP 网络应用程序; 开发异步、非阻塞的 UDP 网络应用程序; 开发异步文件传输应用程序; 开发异步 HTTP 服
Whatspay将有望充当未来数字货币交易“媒介”桥梁
货币发展大致遵循由自然货币向人工货币的演变,由杂乱形状向规范形状的演变,由地方铸币向中央铸币的演变,由金属货币向纸币交子的演变,由手工印币向机制印币的演变。这是一个由复杂向简单,由杂乱向规则,由繁冗向快捷,由沉重向轻便的发展过程。近几十年来,世界经济进一步呈现全球化趋势,各经济体之间的经济联系更加紧密,全球金融市场跨越了地域的限制,产品种类、交易频率、规模是以前所无法比拟的。纸币已经无法满足这样的...