2012-10-18 25 views
2
public class test { 

    public static void main(String[] args) throws Exception { 

     final int num = 111; 

     new Thread() { 
      @Override 
      public void run() { 
       num = 222; 
      } 
     }.start(); 

    } 
} 

我想更改num的值,但是我只能这样做,如果我将其设置为final,这不会让我修改此值。在其他语言如C中,我们可以使用指针,但Java不能?麻烦理解为什么我不能在方法外修改变量?

+0

作为标准的解决方法,使用'final int [] num = {111};'和'num [0] = 222;'。 –

回答

3

Java既没有关闭也没有指针。

一种解决方案是使NUM在类静:

public class test { 
    static int num = 111; 
    public static void main(String[] args) throws Exception { 
     new Thread() { 
      @Override 
      public void run() { 
       num = 222; 
      } 
     }.start(); 
    } 
} 

另一解决方案是使用一个对象像AtomicInteger。你不能改变的变量的值,但你可以改变价值的内容:

public class test { 
    public static void main(String[] args) throws Exception { 
     final AtomicInteger num = new AtomicInteger(111); 
     new Thread() { 
      @Override 
      public void run() { 
       num.set(222); 
      } 
     }.start(); 
    } 
} 
+0

我以为Java7计划关闭? –

+0

我上次检查时,这应该是在Java 8中。 –

1

你正在创建new Thread() {类作为内部类。不能将外部类变量声明为final。

你不能改变最终的变量引用。

有两种方法可以做到这一点,

1)请NUM静态

2)包裹的物体内部NUM(您可以更新对象的状态,即使你定义引用作为最终) 。

注:两者都不是线程安全的。

-1

是的,你不能赢得这里!您需要将其设置为最终才能访问它,但之后您将无法对其进行修改。你需要看一个不同的方法。

+0

这是Java的一个特性吗? – user1753100

+1

不是一个建设性的答案。 –

+1

这是一个功能。在这里解释:http://stackoverflow.com/questions/4732544/why-are-only-final-variables-accessible-in-anonymous-class – Brian

2

为什么这是不允许的

main是一种方法。与其他编程语言一样,当一个方法返回时,其正文中声明的所有变量超出范围,并且访问它们具有未定义的行为。在某些情况下,他们以前的内存位置将不再有效。

显然,这是一个问题。如果在main已返回之后尝试更改num,则可能会覆盖不属于num的堆栈的一部分。爪哇对这种困难情况的回应是限制你如何分享变量:它们必须是最终的。 Java可以安全地定位它们,即使在函数返回后,读取它们也会产生一致的结果。

的C相当于这个问题是存储和使用局部变量的地址的范围,这东西所有的C程序员被教导要永远做之外。

要避开它,请声明num作为test的成员,创建一个实例并将其传递给它。这消除了局部变量的依赖性,从而消除了限制。

public class test 
{ 
    int num = 111; 

    public static void main(String[] args) throws Exception 
    { 
     test t = new test(); 
     (new Thread(t) { 
      test mytest; 
      Thread(test t) 
      { 
       mytest = t; 
      } 

      @Override 
      public void run() { 
       mytest.num = 222; 
      } 
     }).start(); 
    } 
} 
+0

'this'不存在于静态上下文中。你必须创建一个'Test'的实例。 -1 –

+0

@JanDvorak:我意识到这一点,并彻底改变了我的答案。 – Wug

+0

需要澄清:“Java可以以这种方式安全地定位它们”意味着将它们复制到使用它们的每个内部类。这就是为什么他们以后不能改变的原因。 –

2

那么,你可以访问它,如果你在函数外声明变量。像这样:

public class test { 

private static int num = 111; 

    public static void main(String[] args) throws Exception { 

     new Thread() { 
      @Override 
      public void run() { 
       num = 222; 
      } 
     }.start(); 

    } 
}