84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
有人跟我讲,将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
。