Java Thread , How it comes the answer is A?
The question is from http://www.javacertifications.net/javacert/scjp1.6Mock.jsp
Questions no -20
What is the output for the below code ?
public class Test extends Thread
{
static String sName = "g开发者_JAVA百科ood";
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;
}
}
}
options A)good B)good idea C)good idea good idea Correct answer is : A
Explanations : Change value in local methods wouldn’t change in global in case of String ( because String object is immutable).
None of the answers are correct, and there is no single correct answer.
The Question is very bad because it mixes two entirely separate problems:
- The
sName
parameter of thenameTest()
method hides the static variable of the same name, and changes to the local variable have no effect. - The
nameTest()
starts a thread which changes the static variable in itsrun()
method, and themain()
method prints the variable without waiting for that thread to finish. This is known as a race condition: it's pretty much coincidence which state of the variable will be printed - any of the following is possible:- good
- good 0
- good 0 1
- good 0 1 2
- good 0 1 2 3
Note that method nameTest
has a parameter String sName
, which effectively shadows the static
class member with the same name. So the line
sName = sName + " idea ";
refers to and modifies the local method parameter instead of the static
class member. To access the class member from within the method, it should be qualified with the class name, i.e. Test.sName
.
In the run
method, the static sName
member is modified, though, so eventually it becomes something like "good 0 1 2 3". However, there is a race condition between the main thread which (implicitly) starts the thread t
then prints the value of sName
, and the child thread which modifies the same value. Since there is no synchronization involved, it is entirely possible that the main thread prints the value before it is modified by the other thread (i.e. "good"). The outcome could also be "good 0", "good 0 1" etc. However, of all these, only "good" is listed. So A is the only possible answer.
The answer is at this method:
public void nameTest(String sName){
sName = sName + " idea ";
start();
}
There, the assignation on sName
is referred to the input parameter sName
, and not to the static value Test.sName
.
So, when at the run()
method you access the static member, you will get the initial value ("good"
)
The method nameTest is modifying the local parameter sName instead of the static parameter. hence the output is "Good".
For modifying the static parameter, I think you need to use Test.sName
In this case, there is a trap in the nameTest
method. Note that the method parameter name is the same as the static variable name.
In Java, variables resolution says that in this case, the parameter is accessed, and the static variable his "hidden". If you want to access the static variable, you have to use Test.sName
.
So, in this example, "idea" is never appended to the static sName
variable. The only answer available that doesn't include "idea" is A, so 1 is the good answer.
This will output 'good' When you call nameTest(sName) you are only passing in a copy of a reference so any changes so when in the context of nameTest you are working on a different variable. This means that any attempt to reassign this variable wont take affect outside nameTest. The global static variable sName is also hidden by the parameter sName. If string was not immutable it would be possible to make changes to them.
In methods you always deal with local reference COPY (if you give it as an arg). you changed reference COPY, but source is still the same.
the answer can be good
, good 0
, good 0 1
etc.
Actually running the program returns
good 0 1 2 3
(actually wrote it out and tried running it in java... you should try it).
Stepping through the program, we can think of it this way:
In the function nameTest, sName is a local String variable.
Like the explanation says, Strings are immutable so doing a string concatenation with " idea " will create a new instance of a String -- "good idea " -- and assign it to the local variable sName. The class variable sName ( I think calling it shouldn't be called a global ) will remain as "good" as a result.
It then proceeds to run the thread function using start() -- which invokes run().
In the function run(), we do concatenation once again, but this time we assign to the class variable sName.
So when the run() function returns, the class variable sName is changed and the print out will reflect that.
精彩评论