Java学习拾遗1--关于默认值

JVM将为类的instance和static变量赋上缺省值(默认值),包括数组array中的每一个元素--而不用再写初始化赋值语句。

切记:局部变量是没有缺省值的,必须手动初始化!并且这一缺省赋值过程是在对象的构造函数调用之前完成的。

我们看下边的程序:

public class Test {
public static void main(String[] args){
SubClass subClass = new SubClass();
System.out.println(subClass.getObj());
}
}
class SuperClass {
public SuperClass() {
init();
}
protected void init() {
}
}
class SubClass extends SuperClass {
private Object obj;// 如果换成obj = null 呢?
protected void init() {
obj = "abcdefg";
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}

这个的输出为abcdefg,而换成obj=null则输出为null。

这个子类覆盖了父类的init()方法。

其实在子类运行构造函数的时候就使用了super()调用父类的构造函数,而在父类的构造函数中调用了init()方法,而此时子类已经有init()方法覆盖了父类的init()方法,所以此时调用的实际上是子类的init()方法.(这也告诉我们,一般不要再构造方法中调用可能被重写的方法,这可能会给程序带来很多问题。)

而修改后却输出null,追寻这个的原因又引出了一个Java初始化顺序的问题:

新建一java对象(上面main方法中new SubClass())时,它的内部初始化顺序为:

1. 父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行

2. 子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行

3. 父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行

4. 父类构造方法

5. 子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行

6. 子类构造方法

我们分析一下:

那么在private Object obj;中,依次执行了3(无操作)、4(赋值abcdefg)、5(无操作)、6(无操作)=>输出为abcdefg

那么在private Object obj=null;中,依次执行了3(无操作)、4(赋值abcdefg)、5(修改引用为null)、6(无操作)=>输出为null

这就是add()方法的多态性体现。要是将add()方法的权限修改为private,则两个程序的输出都是null,因为类中所有的private方法都隐式地指定是final的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值