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 {
   }
}

==========

当我写上面的代码时,它抛出了一个错误,说“不能引用内部类中的非最终变量”。所以我实现了 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 中没有显示任何错误。我想知道,为什么它现在接受内部类中的变量,即使它不是最终的。它不应该因同样的错误而失败吗?现在可以吗?任何帮助都会很棒。

4

3 回答 3

3

在您的第一个示例someString中是一个局部变量test。您不能引用非最终局部变量,因为内部类将无法观察到该值的更改。通过将该变量声明为final,在内部类中保留了一个附加引用(并且该变量的值在创建实例时已经知道)。

在第二个示例someString中,不是局部变量,而是实例变量。内部类可以从容器对象中引用该变量。

于 2013-03-18T14:44:21.960 回答
2

在第二种情况下,变量是一个生命周期与其包含对象相同的字段。

在第一种情况下,变量是方法的本地变量。它的生命周期可能比方法中创建的匿名类实例短。创建匿名类实例时需要其值的副本。

于 2013-03-18T14:44:12.487 回答
0

正如您所见,Java 编译器不会让您在内部类中引用非 final 的瞬态变量。您可以参考Eclipse 建议您创建的类变量。这是 Java 设计的。您实际上指的是内部类中的此类变量,而不是瞬态变量。

您可能想在此处阅读最终变量和内部类

于 2013-03-18T14:45:32.287 回答