问题来自http://www.javacertifications.net/javacert/scjp1.6Mock.jsp
问题没有-20
以下代码的输出是什么?
public class Test extends Thread
{
static String sName = "good";
public static void main(String argv[])
{
Test t = new Test();
t.nameTest(sName);
System.out.println(sName);
}
public void nameTest(String sName)
{
sName = sName + " idea ";
start();
}
public void run()
{
for(int i=0;i < 4; i++)
{
sName = sName + " " + i;
}
}
}
选项 一个好的 B)好主意 C)好主意好主意 正确答案是:A
解释:在String的情况下,本地方法中的更改值不会在全局变化(因为String对象是不可变的)。
答案 0 :(得分:8)
没有一个答案是正确的,也没有一个正确答案。
问题非常糟糕,因为它混合了两个完全不同的问题:
sName
方法的nameTest()
参数隐藏了同名的静态变量,对局部变量的更改无效。nameTest()
启动一个线程,该线程在其run()
方法中更改静态变量,main()
方法打印变量而不等待该线程完成。这被称为竞争条件:将打印变量的状态非常巧合 - 以下任何一种情况都是可能的:
答案 1 :(得分:3)
请注意,方法nameTest
有一个参数String sName
,它有效地隐藏了具有相同名称的static
类成员。这一行
sName = sName + " idea ";
指的是修改本地方法参数而不是static
类成员。要从方法中访问类成员,应使用类名限定,即Test.sName
。
在run
方法中,static sName
成员被修改,但最终它变成了“good 0 1 2 3”。但是,主线程(隐式)启动线程t
然后打印sName
的值,以及修改相同值的子线程之间存在竞争条件 。由于不涉及同步,所以主线程完全有可能在之前打印值,然后由另一个线程(即“好”)修改它。结果也可能是“好0”,“好0 1”等。但是,在所有这些中,仅列出了“好”。所以 A是唯一可能的答案。
答案 2 :(得分:1)
答案是这个方法:
public void nameTest(String sName){
sName = sName + " idea ";
start();
}
在那里,sName
上的分配是指输入参数sName
,而不是静态值Test.sName
。
因此,当您使用run()
方法访问静态成员时,您将获得初始值("good"
)
答案 3 :(得分:1)
方法nameTest正在修改本地参数sName而不是静态参数。因此输出是“好”。
为了修改静态参数,我认为您需要使用Test.sName
答案 4 :(得分:0)
在这种情况下,nameTest
方法中存在陷阱。请注意,方法参数名称与静态变量名称相同。
在Java中,变量解析表明在这种情况下,访问参数,静态变量为“hidden”。如果要访问静态变量,则必须使用Test.sName
。
因此,在此示例中,“idea”永远不会附加到静态sName
变量。唯一没有包含“想法”的答案是A,所以1是个好答案。
答案 5 :(得分:0)
这将输出'good' 当你调用nameTest(sName)时,你只传递一个引用的副本,所以任何更改,所以在nameTest的上下文中你正在处理另一个变量。这意味着任何重新分配此变量的尝试都不会影响nameTest外部。全局静态变量sName也被参数sName隐藏。 如果string不是不可变的,那么就可以对它们进行更改。
答案 6 :(得分:0)
在方法中,您始终处理本地参考COPY(如果您将其作为arg提供)。你更改了引用COPY,但源仍然相同。
答案可以是good
,good 0
,good 0 1
等。
答案 7 :(得分:0)
实际运行程序返回
好0 1 2 3
(实际写出来并尝试在java中运行它......你应该尝试一下)。
通过该计划,我们可以这样想:
在函数nameTest中,sName是一个本地String变量。
就像解释说的那样,字符串是不可变的,因此使用“idea”进行字符串连接将创建字符串的新实例 - “好主意” - 并将其分配给局部变量sName。类变量sName(我认为调用它不应该被称为全局)将作为结果保持“良好”。
然后继续使用start()运行线程函数 - 它调用run()。
在函数run()中,我们再次进行连接,但这次我们分配给类变量sName。
因此,当run()函数返回时,类变量sName被更改,打印输出将反映出来。