JAVA笔试题总结3:父类构造器调用被子类重写方法
2012-06-15 15:38
393 查看
题目:
请看下列程序,运行结果是
class Super{
int i = 10;
Super(){
print();
i = 20;
}
void print(){
System.out.print(i);
}
}
public class Sub extends Super{
int j = 30;
Sub(){
print();
j = 40;
}
void print(){
System.out.print(j);
}
public static void main(String[] args) {
System.out.print(new Sub().j);
}
}
分析:
先了解这段代码在编译后的执行逻辑.
使用javap工具
将源代码编译为Sub.class 文件后,执行javap -c Sub.class命令,看到如下输出:
在第一步中,声明了变量j。
第二步中,调用父类构造器方法。
第三步,j 赋值30.
第四步,j 赋值40.
需注意,程序可以在3个地方对实例变量执行初始化:
1.定义实例变量时指定初始值。
2.非静态初始化块中为实例变量指定的初始值。
3.构造器中对实例变量指定初始值。
其中1,2种方式比第3种方式更早执行。但1,2种方式的执行顺序与他们在代码中排列顺序一致。
我们通过javap工具编译后发现,无论使用哪种方式赋值,赋值语句最终都被编译器合并到构造器中。而且注意:通过1,2种方式的赋值语句,在合并后总是位于构造器所有语句之前执行(除了调用父类构造器方法)。
所以sub类最终的运行过程是,首先声明变量 j ,为其分配内存空间,此时为默认值:0,然后调用父类构造器,接着按代码中的顺序,将代码中通过1,2种方式赋值的语句合并到构造器中(本题仅涉及到第一种方式的赋值,将j 赋值30,将j 赋值为40为第3种方式)。
其实说了这么多,和本题有关的,只是为了让大家先知道一点:在调用父类构造器时,j 的值为0.
首先程序运行main方法中的System.out.print(new Sub().j);
此时会按截图中的顺序初始化Sub类。
运行到第二步调用父类构造器。
父类构造器调用被子类重写的print()方法。
也就是说Super类的构造器,实际调用的方法是System.out.print(j);
此时j 的值是0,所以,先输出0.
然后按截图中所示的顺序,运行步骤3, j 的值变为30,再调用print()方法,输出30.
运行步骤4,j 的值变为40.子类的构造器执行完毕。
最后Sub().j 输出j 的最终值 40.
故最终输出为03040.
答案:03040
----------------------------------------------------------------------------------------------------------------------------
以后会把我做过的java笔试题分析思路分享给大家,希望对即将工作,需要参加笔试的同学有所帮助.
如果我的分析有误,也恳请大家帮忙指正!!
请看下列程序,运行结果是
class Super{
int i = 10;
Super(){
print();
i = 20;
}
void print(){
System.out.print(i);
}
}
public class Sub extends Super{
int j = 30;
Sub(){
print();
j = 40;
}
void print(){
System.out.print(j);
}
public static void main(String[] args) {
System.out.print(new Sub().j);
}
}
分析:
先了解这段代码在编译后的执行逻辑.
使用javap工具
将源代码编译为Sub.class 文件后,执行javap -c Sub.class命令,看到如下输出:
在第一步中,声明了变量j。
第二步中,调用父类构造器方法。
第三步,j 赋值30.
第四步,j 赋值40.
需注意,程序可以在3个地方对实例变量执行初始化:
1.定义实例变量时指定初始值。
2.非静态初始化块中为实例变量指定的初始值。
3.构造器中对实例变量指定初始值。
其中1,2种方式比第3种方式更早执行。但1,2种方式的执行顺序与他们在代码中排列顺序一致。
我们通过javap工具编译后发现,无论使用哪种方式赋值,赋值语句最终都被编译器合并到构造器中。而且注意:通过1,2种方式的赋值语句,在合并后总是位于构造器所有语句之前执行(除了调用父类构造器方法)。
所以sub类最终的运行过程是,首先声明变量 j ,为其分配内存空间,此时为默认值:0,然后调用父类构造器,接着按代码中的顺序,将代码中通过1,2种方式赋值的语句合并到构造器中(本题仅涉及到第一种方式的赋值,将j 赋值30,将j 赋值为40为第3种方式)。
其实说了这么多,和本题有关的,只是为了让大家先知道一点:在调用父类构造器时,j 的值为0.
首先程序运行main方法中的System.out.print(new Sub().j);
此时会按截图中的顺序初始化Sub类。
运行到第二步调用父类构造器。
父类构造器调用被子类重写的print()方法。
也就是说Super类的构造器,实际调用的方法是System.out.print(j);
此时j 的值是0,所以,先输出0.
然后按截图中所示的顺序,运行步骤3, j 的值变为30,再调用print()方法,输出30.
运行步骤4,j 的值变为40.子类的构造器执行完毕。
最后Sub().j 输出j 的最终值 40.
故最终输出为03040.
答案:03040
----------------------------------------------------------------------------------------------------------------------------
以后会把我做过的java笔试题分析思路分享给大家,希望对即将工作,需要参加笔试的同学有所帮助.
如果我的分析有误,也恳请大家帮忙指正!!
相关文章推荐
- java父类调用被子类重写的方法
- Java父类调用被子类重写的方法
- java父类调用被子类重写的方法
- Java 子类未重写的方法调用父类还是子类的问题
- Java__子类中调用父类重写的方法。
- java 通过子类怎么调用父类已经被重写的方法
- JAVA_继承演示03_ExtendsDeamo01.java super关键字 重写父类的方法,中,调用父类的方法
- JAVA_继承演示03_ExtendsDeamo01.java super关键字 重写父类的方法,中,调用父类的方法
- JAVA中子类是否可以可以继承、重写父类的静态方法--总结
- 从父类构造器调用子类覆盖方法看Java初始化过程
- java里重写某个方法后为什么在重写的方法里还要调用父类的该方法?
- java调用祖父类里被父类重写了的实例方法
- Java方法重写到底调用哪儿一个方法,到底用本类还是父类的成员变量
- Java中不要在父类的构造方法中调用会被子类重写的方法
- Java父类对象调用子类实体:方法重写与动态调用
- Java中父类和子类中的方法调用和参数传递总结
- Java父类对象调用子类实体:方法重写与动态调用
- 重写父类方法、super关键字、调用父类构造器——Java
- Java的重写与调用父类方法问题
- java方法重写的时候,一个调用父类还是子类方法的问题