Java 理解为什么不能在方法之外修改变量有困难吗?

Java 理解为什么不能在方法之外修改变量有困难吗?,java,scope,Java,Scope,我想更改num的值,但我只能在将其设置为final时进行更改,这不允许我修改此值。在C等其他语言中,我们可以使用指针,但Java不能?您正在创建新的线程(){类作为内部类。如果不将外部类变量声明为final,则无法访问外部类变量 不能更改最终变量引用 有两种方法可以做到这一点 1) 将num设置为静态 2) 在对象内包装num(即使将引用定义为final,也可以更新对象的状态) 注意:两者都不是线程安全的。是的,您不能在这里获胜!您需要将其设置为final才能访问它,但之后您将无法修改它。您需要

我想更改
num
的值,但我只能在将其设置为
final
时进行更改,这不允许我修改此值。在C等其他语言中,我们可以使用指针,但Java不能?

您正在创建
新的线程(){
类作为内部类。如果不将外部类变量声明为final,则无法访问外部类变量

不能更改最终变量引用

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

1) 将num设置为静态

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


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

是的,您不能在这里获胜!您需要将其设置为final才能访问它,但之后您将无法修改它。您需要查看不同的方法。

Java既没有闭包也没有指针

解决方案是在类中使num为静态:

public class test {

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

        final int num = 111;

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

    }
}
另一种解决方案是使用如下对象。您不能更改变量的值,但可以更改值的内容:

public class test {
    static int num = 111;
    public static void main(String[] args) throws Exception {
        new Thread() {
            @Override
            public void run() {
                num = 222;
            }
        }.start();
    }
}
为什么这是不允许的
main
是一种方法。与其他编程语言一样,当方法返回时,其主体中声明的所有变量都超出范围,并且访问它们的行为未定义。在某些情况下,它们以前所在的内存位置将不再有效

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

这个问题的C等价物是在其作用域之外存储和使用局部变量的地址,这是所有C程序员都被教导永远不会做的事情

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

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();
    }
}

如果在函数外部声明变量,则可以访问它。如下所示:

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();
    }
}

作为标准的解决方法,使用
final int[]num={111};
num[0]=222;
。这是Java的一个功能吗?这是一个功能。这里解释得很好:
这个
在静态上下文中不存在。您必须创建一个
测试
的实例-1@JanDvorak:我意识到了这一点,并彻底改变了我的答案。需要澄清的是:“Java可以以这种方式安全地找到它们”这意味着将它们复制到每个使用它们的内部类。这就是为什么以后不能更改它们。我以为Java7计划有闭包?上次我检查时,应该是在Java8中。
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();

    }
}