0
public class Knowing {

    static final long tooth = 343L;

    static long doIT(long tooth) {
        System.out.print(++tooth + " ");
        return ++tooth;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        System.out.print(tooth + " ");
        final long tooth = 340L;

        new Knowing().doIT(tooth);
        System.out.println(tooth);
    }
}

さて、ここに私の質問があります:

  • グローバル変数が宣言されている場合static final long tooth = 343L;、メイン メソッドで別の変数を宣言するにはどうすればよいfinal long tooth = 340L;ですか。実行してエラーがなかったので、なぜこれが許可されているのかを知りたいだけです。

  • また、新しいinstance.variable名を作成するのではなく、 className.variableNameを使用してグローバル静的変数の歯にアクセスするべきではありませんか?警告のみで許可されるのはなぜですか?

4

5 に答える 5

7

main メソッドで別の変数をどうすれば宣言できますか 最終的な長い歯 = 340L;

言語仕様には、できると書かれているからです。JLS のセクション 6.4.1から、シャドウイングについて:

d のスコープ全体で、n という名前のローカル変数または例外パラメーターの宣言 d、(a) d が発生した時点でスコープ内にある、n という名前の他のフィールドの宣言、および (b) 任意の宣言d が発生した時点でスコープ内にあるが、d が宣言されている最も内側のクラスで宣言されていない n という名前の他の変数。

これを行う必要がありますか?めったに。一方で、それが問題になることもめったにありません。

2 番目の質問:

また、新しい instance.variable 名を作成するのではなく、className.variableName を使用してグローバル静的変数の歯にアクセスするべきではありませんか?警告のみで許可されるのはなぜですか?

これは Java、IMO の設計上の欠陥です。警告でさえ、言語仕様の一部ではありません。コードが実行しているように見える以外のことを実行するため、これを行うことは常に避ける必要があります。私が通常与える例は次のとおりです。

Thread backgroundThread = new Thread(someRunnable);
backgroundThread.start();
backgroundThread.sleep(1000);

これにより、新しいスレッドではなく、実行中のスレッドがスリープ状態になります。

于 2012-06-12T18:19:22.153 に答える
2

ローカル変数はグローバルを覆い隠します。ただし、classname.variable を使用してグローバルにアクセスすることはできます。

于 2012-06-12T18:17:59.250 に答える
1

tooth変数 inはローカル変数であり、mainグローバル変数よりも優先されます。グローバルにアクセスしたい場合は、次のように参照する必要がありますthis.tooth

変数とスコープについて詳しく知りたい場合は、 Oracle Docsを読むことをお勧めします。

于 2012-06-12T18:18:53.670 に答える
1

パラメーター/変数の非表示は、言語設計の一般的な機能です。たとえば、サードパーティ ライブラリのメソッドのクライアントが、そのライブラリが仮パラメータに使用する名前を制御する方法はありません。言語設計におけるもう 1 つの一般的な慣例は、一貫性です。つまり、変数を宣言できる場所ならどこでも、同じ名前の変数を外側のスコープから隠すことができます。同じスコープ内の変数と同じ名前のローカル変数を宣言しようとすると、コンパイラからエラーが発生することに注意してください。

Builder パターンを使用する場合、静的変数への非静的アクセスは便利な機能です。ただし、それは欺瞞的であるため(別の回答がグラフィカルに示しているように)、コンパイラは警告としてフラグを立てます。

于 2012-06-12T18:21:03.263 に答える
1

まず、className.variableName is a legal way of accessing a static member, but its possible to create an instance of the class which has the static memberその静的メンバーにアクセスします。これはバグまたは欠陥と考えてください。コンストラクターがプライベートである Math のようなクラスでは不可能になり、さらにそのクラスにはインスタンス変数がないため、オブジェクトを作成しても意味がありません。スコープについては、このリンクを参照してください http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.4.1

于 2012-06-12T18:25:42.683 に答える