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 :(得分: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();
}
}
答案 1 :(得分: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();
}
}
答案 2 :(得分: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();
}
}
答案 3 :(得分:1)
您正在创建new Thread() {
类作为内部类。如果不将它们声明为最终变量,则无法访问外部类变量。
您无法更改最终变量引用。
有两种方法可以做到这一点,
1)将num设为静态
2)在对象中包装num(即使您将引用定义为final,也可以更新对象的状态)。
注意:两者都不是线程安全的。
答案 4 :(得分:-1)