我是Java的新手,并且几天以来一直在做一些基本的编码。今天在处理变量和内部类时,我在内部类中使用非final变量时陷入困境。
我正在使用testNG框架进行工作,所以这是我正在尝试的方案,
======
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 {
}
}
==========
当我编写上面的代码时,它抛出一个错误,说“不能引用内部类中的非final变量”。所以我实现了eclips提供的一个建议,即在父类中声明someString变量。现在代码看起来像这样,
==========
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 {
}
}
==========
现在它没有在eclips中显示任何错误。 我想知道,为什么它现在接受内部类中的变量,即使它不是最终的。不应该失败并出现同样的错误吗?这会有效吗?任何帮助都会很棒。
答案 0 :(得分:3)
在您的第一个示例中,someString
是test
中的局部变量。您不能引用非最终局部变量,因为内部类将无法观察到该值的更改。通过将该变量声明为final
,在内部类中保留了一个额外的引用(并且在创建实例时已知该变量的值)。
在第二个示例中,someString
不是本地变量,而是实例1。内部类可以从容器对象引用该变量。
答案 1 :(得分:2)
在第二种情况下,变量是一个字段,其生命周期与其包含的对象相同。
在第一种情况下,变量是方法的本地变量。它的生命周期可能比方法中创建的匿名类实例短。创建匿名类实例时,需要其值的副本。
答案 2 :(得分:0)
正如您所见,Java编译器不会让您引用内部类中不是最终的瞬态变量。您可以参考Eclipse建议您创建的类变量。这是Java设计的。您实际上是在内部类中引用此类变量而不是瞬态变量。
您可能想要阅读最终变量和内部类here