簡體   English   中英

難以理解為什么我不能在方法外部修改變量?

[英]Trouble understanding why I cannot modify variable outside a method?

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

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

為什么不允許這樣做

main是一種方法。 與其他編程語言一樣,當方法返回時,在其主體中聲明的所有變量都超出范圍,並且對其進行訪問具有未定義的行為。 在某些情況下,它們以前所在的存儲位置將不再有效。

顯然這是一個問題。 如果在main返回后嘗試更改num ,則可能會覆蓋堆棧中不再屬於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();
    }
}

好吧,如果您在函數外部聲明變量,則可以訪問它。 像這樣:

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

    }
}

您正在創建new Thread() {類作為內部類。 您必須將外部類變量聲明為final才能訪問它們。

您不能更改最終變量引用。

有兩種方法可以做到這一點,

1)將num設為靜態

2)在對象內包裝num(即使將引用定義為final,也可以更新對象的狀態)。

注意:兩者都不是線程安全的。

是的,您不能在這里贏! 您需要將其最終設置為可以訪問它,但之后將無法對其進行修改。 您需要考慮另一種方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM