Reputation: 131
I am new to Java and have been doing some basic coding since few days. Today while dealing with variables and inner class, I got stuck while using the non-final variable in innerclass.
I am using testNG framework for my work, so here is the scenario that I am trying,
=========
public class Dummy extends TestNG {
@Override
public void setUp() throws Exception {
log.error("Setup Goes here");
}
@Override
public void test() throws Exception {
String someString = null;
try {
someString = "This is some string";
} catch (Exception e) {
log.error(e.getMessage());
}
Thread executeCommand = new Thread(new Runnable() {
@Override
public void run() {
try {
runComeCommand(someString, false); <=====ERROR LINE
} catch (Exception e) {
log.error(e.getMessage());
}
}
});
}
@Override
public void cleanUp() throws Exception {
}
}
==========
When I wrote the above code, it thrown an error saying "can not refer to non-final variable in inner class". So I implemented one of the suggestion provided by eclips i.e declare someString variable in the parent class. Now the code looks like this,
==========
public class Dummy extends TestNG {
String someString = null; <=====Moved this variable from test() to here
@Override
public void setUp() throws Exception {
log.error("Setup Goes here");
}
@Override
public void test() throws Exception {
<same code goes here>
}
@Override
public void cleanUp() throws Exception {
}
}
==========
Now it does not show any error in eclips. I wanna know, Why its now accepting the variable in inner class even though its not final. Shouldn't it fail with the same error? Will this work now? Any help will be great.
Upvotes: 3
Views: 2943
Reputation: 12398
In your first example someString
is a local variable in test
. You cannot reference non final local variables, because the inner class will not be able to observe changes to that value. By declaring that variable as final
, an additional reference is kept in the inner class (and the value of that variable is already known when the instance is created).
In the second example someString
is not a local variable but an instance one. The inner class can reference that variable from the container object.
Upvotes: 3
Reputation: 1235
The Java compiler will not let your refer to transient variables that are not final in inner classes, as you have seen. You can refer to your class variable that Eclipse suggested your create. This is by design in Java. You are actually referring to this class variable in your inner class and not your transient variables.
You may want to read up on final variables and inner classes here
Upvotes: 0
Reputation: 86391
In the second case, the variable is a field whose lifetime is the same as its containing object.
In the first case, the variable is local to the method. Its lifetime may be shorter than the anonymous class instance created in the method. A copy of its value is needed when the anonymous class instance is created.
Upvotes: 2