有人跟我讲,将name进行静态赋值即可,但实例变量不也是属于成员变量吗,也是在整个类实例化的时候产生的啊,跟静态赋值有何区别吗?
人生最曼妙的风景,竟是内心的淡定与从容!
父類別的建構方法先於子類別建構方法執行,Base()->test()-->name.length()相当于null.length()。将name寫成靜態的話,當然可以了,因為靜態成員的初始化先於實例成員的初始化。
Base()->test()-->name.length()
null.length()
name
順序大概是這樣的:
父類static{...}
static{...}
父類靜態成員
父類構造方法
子類static{...}
子類別靜態成員
子類別構造方法
先拋出一個概念,對象的初始化流程:靜態變數> 靜態初始化區塊> 實例變數> 建構器静态变量 > 静态初始化块 > 实例变量 > 构造器而存在父子类关系的对象,又存在一个嵌套的初始化流程父类初始化流程 > 子类初始化流程而存在父子類別關係的對象,又存在一個嵌套的初始化流程
靜態變數> 靜態初始化區塊> 實例變數> 建構器
静态变量 > 静态初始化块 > 实例变量 > 构造器
父类初始化流程 > 子类初始化流程
父類別初始化流程> 子類別初始化流程
test()方法时,子类的name还没有赋值,仍然是null所以在你實例化的過程中,呼叫父類別建構器並呼叫
test()
null
你把name放在父类Base中定义就不会报错。 因为你实例化Sub时,会调用默认的构造函数,默认的构造函数会调用父类的构造函数,在父类的构造函数中,你使用了test()方法,而你在子类中重写了该方法,子类的test方法内使用了name,但是这时候name还没有完成初始化。所以会报NullPointerException。
Base
Sub
test
NullPointerException
父類別的建構方法先於子類別建構方法執行,
Base()->test()-->name.length()
相当于null.length()
。将
name
寫成靜態的話,當然可以了,因為靜態成員的初始化先於實例成員的初始化。順序大概是這樣的:
父類
static{...}
父類靜態成員
父類構造方法
子類
static{...}
子類別靜態成員
子類別構造方法
先拋出一個概念,對象的初始化流程:
靜態變數> 靜態初始化區塊> 實例變數> 建構器
静态变量 > 静态初始化块 > 实例变量 > 构造器
而存在父子类关系的对象,又存在一个嵌套的初始化流程
父类初始化流程 > 子类初始化流程
而存在父子類別關係的對象,又存在一個嵌套的初始化流程父類別初始化流程> 子類別初始化流程
test()
方法时,子类的name
还没有赋值,仍然是null
所以在你實例化的過程中,呼叫父類別建構器並呼叫你把
name
放在父类Base
中定义就不会报错。 因为你实例化Sub
时,会调用默认的构造函数,默认的构造函数会调用父类的构造函数,在父类的构造函数中,你使用了test()
方法,而你在子类中重写了该方法,子类的test
方法内使用了name
,但是这时候name
还没有完成初始化。所以会报NullPointerException
。