java 对象初始化



验证:确保java类的字节码表示在结构上完全正确。验证过程中有可能导致其他java类或者接口被加载。
若验证过程中发现字节码格式不正确,会抛出java.lang.verfiyError异常。一般通过java编译器生成的字节码不会出现验证错误。
解析:处理所加载的java类中包含的形式引用。

初始化:主要执行java类中的静态代块和初始化静态域。
初始化过程中静态代码快和静态代码域按照在代码中 出现的顺序依次执行
示例:
public class staticOrder{
     public static int x = 10;
     public static int y = 2 0 * x;
     static{
          x = 30;
     }
     public static void main(String args[]){
          System.out.println(y);  //结果是200
     }
}
初始化何时才会发生???
  •  实例化java类时,即使用new关键字
  • 调用java类中的静态方法。
  • 为类和接口中的静态域赋值。
  • 访问类或接口中的声明的静态域,并且该域不是常量。
  • 调用Class类和反射API中进行反射操作的方法会被初始化。
对象实例化:
  1. 先调用父类的构造函数(在子类中会有显示调用super和隐式调用)。
  2. 初始化类中实例域的值,按照代码出现的顺序依次执行。
  3. 然后子类构造方法中其他的代码。
注意:子类构造方法中super()可以省略。但是必须放在子类中的第一行。
任何子类的构造方法(有参或无参)若没有显示调用父类构造方法即super(参数),在java中都会隐式调用super();

下面是来自 酷壳--陈皓 的《Java构造时成员初始化的陷阱 》博客的例子:
publicclass Base{
    Base() {
        preProcess();
    } 
    voidpreProcess() {}
}

publicclass Derived extends Base{
    publicString whenAmISet = "set when declared"; 
    @Overridevoid preProcess(){
        whenAmISet = "set in preProcess()";
    }
}

如果我们构造一个子类实例,那么,whenAmISet 的值会是什么呢?

publicclass Main{
    publicstatic void main(String[] args){
        Derived d = new Derived();
        System.out.println( d.whenAmISet );
    }
}

运行结果是:set wher declared 

why??????

根据上面我们说道;
  • 先调用子类的构造方法,
  • 第一行是隐式super(),调用父类构造方法。在这里实例域 whenAmIset 调用函数preProcess 被赋值set in preProcess()。(这里调用的preProcess是子类的函数,不是父类中的函数)
  • 然后在初始化实例域;whenAmIset 又被赋值为set wher declared 。
  • 最后完成
更详细的流程:
  1. 进入Derived 构造函数。
  2. Derived 成员变量的内存被分配。
  3. Base 构造函数被隐含调用。
  4. Base 构造函数调用preProcess()。
  5. Derived 的preProcess 设置whenAmISet 值为 “set in preProcess()”。
  6. Derived 的成员变量初始化被调用。
  7. 执行Derived 构造函数体

public class test {
     public static void main(String[] args) {
          SuperInitField p = new SuperInitField();      //--------------------  第一行
          SuperInitField c = new SubInitField();
     }
}
class SuperInitField {
     public SuperInitField() {
          System.out.println("parent");
     }
     static {
          System.out.println("static parent");
     }
}
class SubInitField extends SuperInitField {
     public SubInitField() {
          System.out.println("child");
     }
     static {
          System.out.println("static child");
     }
}
运行结果: static parent
                    parent
                    static child
                    parent
                    child
假设将 第一行注释掉
结果又是什么呢?
答案:          
static parent 
  static child
  parent
child
          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值