我做到了一个很奇怪的Java认证考题,始终不解,恳请那位知道的网友帮忙解释一下好吗?
题目是这样的:
What is the output when the user runs "java TestA"?
以下内容为程序代码
--------------------------------------------------------------------------------
public class TestA
{
TestA()
{
System.out.println("P ");
this.init();
}
void init()
{
System.out.println("Q ");
}
public static void main(String[] args)
{
TestB testb=new TestB();
}
}
class TestB extends TestA
{
int i=1;
TestB()
{
super();
System.out.println(i+" ");
}
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
}
--------------------------------------------------------------------------------
A. P Q 1
B. P C 0 2
C. P C 1 1
D. P C 2 2
E. P C 2 1
F. P Q 0
这道题的正确答案是E.我看这到题目的答案好象是D.可是运行了一遍程序,E答案是正确的。这是为什么呢?想了好半天,始终不解!!!
1.这最后一个1好象是调用了TestB类中的Constructor的super()后,调用了System.out.println(i+" ");的结果,可是实例变量i已被初始化为2,怎么又会边1了呢?
我想关键就是以上这两条,那位知道的网友可以帮我详细的解释一下吗?谢谢了
11 个解决方案
#1
你分析这段程序的时候,注意这几点:
1.Class TestB的父类Class TestA中,对init()方法进行了重置.
2.在TestA中申明的是它的子类,那么调用TestB执行时this这个关键子当然就是指向TestB这个类,尽管在TestB的构造器中已经显式的调用了super(),因此首先打印"P".
3.在TestA中执行this.init()方法时,this实际上是指向TestB类,因此就执行TestB类中重置的init()方法,打印"C".
4.this.i=2,这句话就是修改TestB类的成员变量i的值,因此System.out.println(i+"");自然就打印2出来.
5.在回到TestB的构造器去执行System.out.println(i+"")这句话,注意这里应该再次打印出来的是2呀,怎么还是1呀???????????????????????????
不知你知道这个知识点吗?调用this这个关键字对变量进行操作时就相当于参数值传递,实际上只是在方法内部临时修改变量的值,它操作的只是这个类成员变量的一份拷贝
这下你该清楚了吧
1.Class TestB的父类Class TestA中,对init()方法进行了重置.
2.在TestA中申明的是它的子类,那么调用TestB执行时this这个关键子当然就是指向TestB这个类,尽管在TestB的构造器中已经显式的调用了super(),因此首先打印"P".
3.在TestA中执行this.init()方法时,this实际上是指向TestB类,因此就执行TestB类中重置的init()方法,打印"C".
4.this.i=2,这句话就是修改TestB类的成员变量i的值,因此System.out.println(i+"");自然就打印2出来.
5.在回到TestB的构造器去执行System.out.println(i+"")这句话,注意这里应该再次打印出来的是2呀,怎么还是1呀???????????????????????????
不知你知道这个知识点吗?调用this这个关键字对变量进行操作时就相当于参数值传递,实际上只是在方法内部临时修改变量的值,它操作的只是这个类成员变量的一份拷贝
这下你该清楚了吧
#2
E是正确答案
你应该看到的是,在MAIN中运行的是TestB,所以你只关心TestB怎么运行的了,首先运行P是没问题的,然后INIT被重载了,输出C好象也没问题。然后是输出2是没问题的,
而I在TESTB中是个“INSTANCE”变量,当跳出INIT后I 就是 1 了啊!
你应该看到的是,在MAIN中运行的是TestB,所以你只关心TestB怎么运行的了,首先运行P是没问题的,然后INIT被重载了,输出C好象也没问题。然后是输出2是没问题的,
而I在TESTB中是个“INSTANCE”变量,当跳出INIT后I 就是 1 了啊!
#3
我认为,以上两位的答案均是错误的。
实际上,出现E答案,原因在于实例化一个类时,该类的成员变量init的顺序。在think in java 里面说的很清楚。
1.locate :也就是找到这个类的位置。
2。allocate&static:收集内存,初始化静态成员变量
3。zero:将“INSTANCE”变量置为零或则null;
4.执行父类的构造(输出2是没问题的)
5.init :将“INSTANCE”变量初始化,即将i重新置为1
6。执行本类的构造,故输出得到i=1了
实际上,出现E答案,原因在于实例化一个类时,该类的成员变量init的顺序。在think in java 里面说的很清楚。
1.locate :也就是找到这个类的位置。
2。allocate&static:收集内存,初始化静态成员变量
3。zero:将“INSTANCE”变量置为零或则null;
4.执行父类的构造(输出2是没问题的)
5.init :将“INSTANCE”变量初始化,即将i重新置为1
6。执行本类的构造,故输出得到i=1了
#4
我查了相关的资料,二楼的说法是错误的。城如楼上所说,这与构造器中初始化的顺序有关。
#5
请问楼上所解释的在第5步中提到实例变量重新被初始化,这一步有什么根据?
请注意在类中,对方法的重载(overload)和方法的重置(override)这两者是根本不同的
请注意在类中,对方法的重载(overload)和方法的重置(override)这两者是根本不同的
#6
一个对象建立时候初始化顺序:
1 static and static block的代码部分初始化
2 调用构造器中的super();父类开始初始化
3 当前类的非static 和block初始化
4 构造器其它代码执行
如上:
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
i=2后,子类的非static 有初始化,把i = 1
所以E
1 static and static block的代码部分初始化
2 调用构造器中的super();父类开始初始化
3 当前类的非static 和block初始化
4 构造器其它代码执行
如上:
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
i=2后,子类的非static 有初始化,把i = 1
所以E
#7
我发现这个帖子,怎么贴了好几个地方?
而且,正确答案应该已经得到了,楼主怎么还不依不饶啊?
而且,正确答案应该已经得到了,楼主怎么还不依不饶啊?
#8
E是正确的,
因为,成员变量i的初始化是在super运行之后进行的,因此,你在init中将i赋值成2,而在super结束之后才执行初始化所以i的值又成了1
因为,成员变量i的初始化是在super运行之后进行的,因此,你在init中将i赋值成2,而在super结束之后才执行初始化所以i的值又成了1
#9
在july_typhoon(加油的风)给出的六个步骤中,第四步调用父类的构造函数后,在第六步中调用自身的构造函数中又调用了super(),为什么父类的构造函数只执行了一次,而不是两次??
#10
如果你不调用super()会隐式的调用父类的却省构造函数,如果你显式的使用了super()就不会在调用了,super()主要是用来调用父类的代参构造函数
#11
呵呵,来晚了, and up!
#1
你分析这段程序的时候,注意这几点:
1.Class TestB的父类Class TestA中,对init()方法进行了重置.
2.在TestA中申明的是它的子类,那么调用TestB执行时this这个关键子当然就是指向TestB这个类,尽管在TestB的构造器中已经显式的调用了super(),因此首先打印"P".
3.在TestA中执行this.init()方法时,this实际上是指向TestB类,因此就执行TestB类中重置的init()方法,打印"C".
4.this.i=2,这句话就是修改TestB类的成员变量i的值,因此System.out.println(i+"");自然就打印2出来.
5.在回到TestB的构造器去执行System.out.println(i+"")这句话,注意这里应该再次打印出来的是2呀,怎么还是1呀???????????????????????????
不知你知道这个知识点吗?调用this这个关键字对变量进行操作时就相当于参数值传递,实际上只是在方法内部临时修改变量的值,它操作的只是这个类成员变量的一份拷贝
这下你该清楚了吧
1.Class TestB的父类Class TestA中,对init()方法进行了重置.
2.在TestA中申明的是它的子类,那么调用TestB执行时this这个关键子当然就是指向TestB这个类,尽管在TestB的构造器中已经显式的调用了super(),因此首先打印"P".
3.在TestA中执行this.init()方法时,this实际上是指向TestB类,因此就执行TestB类中重置的init()方法,打印"C".
4.this.i=2,这句话就是修改TestB类的成员变量i的值,因此System.out.println(i+"");自然就打印2出来.
5.在回到TestB的构造器去执行System.out.println(i+"")这句话,注意这里应该再次打印出来的是2呀,怎么还是1呀???????????????????????????
不知你知道这个知识点吗?调用this这个关键字对变量进行操作时就相当于参数值传递,实际上只是在方法内部临时修改变量的值,它操作的只是这个类成员变量的一份拷贝
这下你该清楚了吧
#2
E是正确答案
你应该看到的是,在MAIN中运行的是TestB,所以你只关心TestB怎么运行的了,首先运行P是没问题的,然后INIT被重载了,输出C好象也没问题。然后是输出2是没问题的,
而I在TESTB中是个“INSTANCE”变量,当跳出INIT后I 就是 1 了啊!
你应该看到的是,在MAIN中运行的是TestB,所以你只关心TestB怎么运行的了,首先运行P是没问题的,然后INIT被重载了,输出C好象也没问题。然后是输出2是没问题的,
而I在TESTB中是个“INSTANCE”变量,当跳出INIT后I 就是 1 了啊!
#3
我认为,以上两位的答案均是错误的。
实际上,出现E答案,原因在于实例化一个类时,该类的成员变量init的顺序。在think in java 里面说的很清楚。
1.locate :也就是找到这个类的位置。
2。allocate&static:收集内存,初始化静态成员变量
3。zero:将“INSTANCE”变量置为零或则null;
4.执行父类的构造(输出2是没问题的)
5.init :将“INSTANCE”变量初始化,即将i重新置为1
6。执行本类的构造,故输出得到i=1了
实际上,出现E答案,原因在于实例化一个类时,该类的成员变量init的顺序。在think in java 里面说的很清楚。
1.locate :也就是找到这个类的位置。
2。allocate&static:收集内存,初始化静态成员变量
3。zero:将“INSTANCE”变量置为零或则null;
4.执行父类的构造(输出2是没问题的)
5.init :将“INSTANCE”变量初始化,即将i重新置为1
6。执行本类的构造,故输出得到i=1了
#4
我查了相关的资料,二楼的说法是错误的。城如楼上所说,这与构造器中初始化的顺序有关。
#5
请问楼上所解释的在第5步中提到实例变量重新被初始化,这一步有什么根据?
请注意在类中,对方法的重载(overload)和方法的重置(override)这两者是根本不同的
请注意在类中,对方法的重载(overload)和方法的重置(override)这两者是根本不同的
#6
一个对象建立时候初始化顺序:
1 static and static block的代码部分初始化
2 调用构造器中的super();父类开始初始化
3 当前类的非static 和block初始化
4 构造器其它代码执行
如上:
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
i=2后,子类的非static 有初始化,把i = 1
所以E
1 static and static block的代码部分初始化
2 调用构造器中的super();父类开始初始化
3 当前类的非static 和block初始化
4 构造器其它代码执行
如上:
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
i=2后,子类的非static 有初始化,把i = 1
所以E
#7
我发现这个帖子,怎么贴了好几个地方?
而且,正确答案应该已经得到了,楼主怎么还不依不饶啊?
而且,正确答案应该已经得到了,楼主怎么还不依不饶啊?
#8
E是正确的,
因为,成员变量i的初始化是在super运行之后进行的,因此,你在init中将i赋值成2,而在super结束之后才执行初始化所以i的值又成了1
因为,成员变量i的初始化是在super运行之后进行的,因此,你在init中将i赋值成2,而在super结束之后才执行初始化所以i的值又成了1
#9
在july_typhoon(加油的风)给出的六个步骤中,第四步调用父类的构造函数后,在第六步中调用自身的构造函数中又调用了super(),为什么父类的构造函数只执行了一次,而不是两次??
#10
如果你不调用super()会隐式的调用父类的却省构造函数,如果你显式的使用了super()就不会在调用了,super()主要是用来调用父类的代参构造函数
#11
呵呵,来晚了, and up!