2011-01-07 5 views
4

私はシャドーイングについて理解できません。たとえば、次のコードJavaの可変スコープとシャドーイングに関する質問

class Foo { 
    int a = 5; 
    void goFoo(int a) { 
     // No problem naming parameter as same as instance variable 
     for (int a = 0; a < 5; a++) { } 
     //Now the compiler complains about the variable a on the for loop 
     // i thought that the loop block had its own scope so i could shadow 
     // the parameter, why the compiler didnt throw an error when i named 
     // the parameter same as the instance variable? 
    } 
} 

ありがとうございました。

答えて

2
void goFoo(int a) { 

     for (int a = 0; a < 5; a++) { } 

} 

、同じスコープにa

void goFoo() { 
     int a; 
     for (int a = 0; a < 5; a++) { } 

} 

ので、複数の宣言に似ている、それは受け入れられません。

または単にそれが

void goFoo() { 
    int a; 
    int a; 
} 

に似ています。また

0

を参照してくださいしかし、あなたは "" という新しいスコープで秒を宣言していません、あなたのコードが示すように。これはgoFoo()ブロック自体のスコープに含まれています。

11

ローカル変数をシャドウインスタンス/静的変数にすることはできますが、1つのローカル変数(ループカウンタ)を別のローカル変数またはパラメータ(パラメータ)にすることはできません。 Java言語仕様から

section 14.4.3

ローカル変数として宣言された名前が既にフィールド名として宣言されている場合、外側の宣言は、スコープ全体(§6.3.1)隠されていることローカル変数

ノート「フィールド名」の部分 - 隠されているフィールドなければならないことを指定ます。

そしてsection 8.4.1から:

方法のパラメータ(§8.4.1)またはコンストラクタ(§8.8.1)の範囲は、メソッドやコンストラクタの本体全体です。

これらのパラメータ名は、メソッドのローカル変数として、またはメソッドまたはコンストラクタのtry文のcatch句の例外パラメータとして再宣言できません。

(これは、ローカルクラスや匿名クラスについて話をしに行くが、彼らはあなたのケースでは無関係です。)

1

変数のスコープは、同様に、ブロックの階層に依存します。

すなわちuが変数は、外側のブロックで宣言されている場合、あなたは、内側のブロックで同じことを宣言することはできません。この

void goFoo(int a) { 
     // No problem naming parameter as same as instance variable 
     for (int b = 0; b < 5; b++) { } 
     //Now the compiler complains about the variable a on the for loop 
     // i thought that the loop block had its own scope so i could shadow 
     // the parameter, why the compiler didnt throw an error when i named 
     // the parameter same as the instance variable? 

     int b; // you can do this. 

    } 

のように使用している場合。それ以外の方法でそれを行うことができます。

0

問題は、ループがクラスフィールドをシャドーイングしているということではなく、名前が既にパラメーターによって使用されています。

つのオプション:一つは、ループを変更することです:

for (a = 0; a < 5; a++) { } 

これは、インデックス変数などのパラメータを使用しています。なぜパラメータがあるのか​​はっきりしませんが、すべて同じです...

もう1つのオプションは、ループ変数またはパラメータの名前を変更することです。

0

シャドーイングではありませんが、ここでは矛盾しています。どちらもaはメソッドスコープにあります。同じスコープ内で同じ名前の2つの変数を定義することはできません。

関連する問題