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 不能?

4

5 回答 5

4

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();
    }
}
于 2012-10-18T14:37:28.193 回答
2

为什么这是不允许的

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

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

与此问题等效的 C 语言是在其范围之外存储和使用局部变量的地址,这是所有 C 程序员都被教导永远不要做的事情。

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

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();
    }
}
于 2012-10-18T14:38:29.327 回答
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();

    }
}
于 2012-10-18T14:38:58.363 回答
1

您正在创建new Thread() {类作为内部类。如果不将它们声明为 final,则无法访问外部类变量。

您不能更改最终变量引用。

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

1) 将 num 设为静态

2) 将 num 包裹在一个对象内(即使您将引用定义为 final,您也可以更新对象的状态)。

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

于 2012-10-18T14:36:08.193 回答
-1

是的,你不能在这里赢!您需要将其设置为 final 才能访问它,但是您将无法对其进行修改。你需要看看不同的方法。

于 2012-10-18T14:37:26.620 回答