zyf4005 2016-05-07 00:23 采纳率: 100%
浏览 1231
已采纳

关于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条回答 默认 最新

  • 毕小宝 博客专家认证 2016-05-09 04: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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥88 实在没有想法,需要个思路
  • ¥15 python中合并修改日期相同的CSV文件并按照修改日期的名字命名文件
  • ¥15 有赏,i卡绘世画不出
  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)