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

関数の外で変数を宣言すればアクセスできます。このような:

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 に答える
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 に答える
1

new Thread() {クラスを内部クラスとして作成しています。final として宣言しないと、外部クラス変数にアクセスできません。

最終的な変数参照は変更できません。

これを行うには2つの方法があります。

1) num を static にする

2) num をオブジェクト内にラップします (参照を final として定義しても、オブジェクトの状態を更新できます)。

注: どちらもスレッド セーフではありません。

于 2012-10-18T14:36:08.193 に答える
-1

はい、ここでは勝てません!アクセスできるように最終的に設定する必要がありますが、変更することはできません。別のアプローチを検討する必要があります。

于 2012-10-18T14:37:26.620 に答える