zoukankan      html  css  js  c++  java
  • 【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/

  • 相关阅读:
    阶乘递归实现
    队列
    1+2+3+...+100用递归实现
    快速排序C语言实现
    js的onfocus,onblur事件
    CSP2021 游记 菜到离谱
    700题复习计划
    [传递闭包] P2881 [USACO07MAR]排名的牛Ranking the Cows
    【笔记】序列分块
    【题解】UVA10930 A-Sequence
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2822327.html
Copyright © 2011-2022 走看看