• 【Java学习笔记】关于默认值


    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    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的。

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

  • 相关阅读:
    codeforces round #433 div2
    bzoj1951
    bzoj3620
    bzoj2286
    bzoj1513
    bzoj4390
    codeforces round 430 div 2
    bzoj3339
    准备实现体积蒙皮
    看牛顿法的改进与验证局部收敛
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2822327.html
Copyright © 2020-2023  润新知