在内部类中使用非final变量

3
我是一名Java新手,已经进行了几天的基础编码。今天在处理变量和内部类时,我在使用内部类中的非最终变量时遇到了困难。
我正在使用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 {
   }
}

当我编写上述代码时,它抛出一个错误,显示“无法引用内部类中的非最终变量”。因此,我实现了Eclipse提供的建议之一,即在父类中声明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 {
   }
}

现在在eclipse中不显示任何错误。 我想知道为什么它现在可以接受内部类中的变量,即使变量不是final的。难道不应该出现相同的错误吗?现在这样会起作用吗?任何帮助都将是有益的。


1
可能是内部类非最终变量java的重复问题。 - Joachim Sauer
3个回答

3
在你的第一个例子中,someStringtest 中的一个局部变量。你不能引用非 final 的局部变量,因为内部类将无法观察到该值的更改。通过将该变量声明为 final,内部类中保留了一个额外的引用(并且在创建实例时已知该变量的值)。
在第二个例子中,someString 不是一个局部变量,而是一个实例变量。内部类可以从容器对象引用该变量。

2
在第二种情况下,变量是一个字段,其生命周期与包含它的对象相同。
在第一种情况下,变量是局部方法变量。其生命周期可能短于在方法中创建的匿名类实例。在创建匿名类实例时需要复制其值。

0
Java编译器不允许在内部类中引用非final的transient变量,正如您所见。您可以引用Eclipse建议您创建的class变量。这是Java的设计。实际上,您在内部类中引用的是这个class变量而不是transient变量。
您可能想要阅读有关final变量和内部类的这里的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接