2009-07-07 6 views
19

私はDeitel、Java How to Programの本を読んでおり、というシャドウイングという用語を見つけました。シャドーイングが許可されている場合、Javaクラスにはどのような状況や目的がありますか?Javaクラスで使用される可変シャドーイングとは何ですか?

例:

public class Foo { 

    int x = 5; 

    public void useField() { 
     System.out.println(this.x); 
    } 
    public void useLocal() { 
     int x = 10; 
     System.out.println(x); 
    } 
} 

答えて

32

シャドウイングの基本的な目的は、ローカルコードを周囲のクラスから切り離すことです。それが利用できなかった場合は、次のケースを考慮する。

APIのクラスFooがリリースされました。コードではサブクラス化し、サブクラスではbarという変数を使用します。その後、Fooは更新をリリースし、そのクラスにBarという保護された変数を追加します。

あなたのクラスは、予想できなかった競合のために実行されません。

ただし、これを目的に使用しないでください。範囲外で何が起きているか本当に気にしないときにのみ、これを起こさせてください。

+7

私はあなたの最終的な点が好きです。「スコープ外で何が起こっているか気にしないときに、これを起こさせてください。 ...インスタンス変数の値で奇妙なことが起き始めたら、いつケアを開始するのか分かります:)))とにかくインスタンスの値を設定しているメソッドの中でthis.variable_nameを使うのは良い方法です変数... – luigi7up

8

一つの主要な目的は、人々を混乱することです。それは悪い習慣であり、避けるべきです。

+0

物議私は;-) –

+6

を前提としますが、さらに全く混乱してどのようにthis.x = xで説明できますか? – RichieHH

13

それはあなただけでメソッドのパラメータのために、例えば、別々の変数名を作成する必要がしたくないセッターのために役立つことができます。別に私はそれらを避けるだろうとの

public void setX(int x) { 
    this.x = x; 
} 

+1

これは、変数をシャドーするのはひどい理由です。シャドーイングでは常にエラーが発生する可能性があります。スコープ情報を持つ変数の名前の変更やパラメータの名前の変更は、「this」を含めるよりも簡単です。毎回。 – Rick

+3

上記の例のようにシンプルなセッターの場合、パラメータの名前を変更すると醜いものになります。これよりも複雑なものは、私は同意し、完全に避けてください。 –

4

シャドウイングは実際にはJavaのみの用語ではありません。スコープで宣言された変数が、より大きなスコープ内の変数と同じ名前を持つ場合、その変数はシャドウされます。

シャドウイングの一般的な用途の1つは、内部クラスと外部クラスがあり、同じ名前の変数を維持する場合です。

あなたがそれを避けることができれば、それは混乱の原因になるはずです。

1

2つの一般的な用途は、コンストラクタおよびsetメソッドです:

public Foo(int x) { 
    this.x = x; 
} 

public void setX(int x) { 
    this.x = x; 
} 

あなたは、単一の瞬間における変数のコピーをしたい場合は、非常に時折、それは便利だが、変数は、メソッドの呼び出し内で変更されることがあります。

private void fire() { 
    Listener[] listeners = this.listeners; 
    int num = listeners.length; 
    for (int ct=0; ct<num; ++ct) { 
     listeners[ct].stateChanged(); 
    } 
} 

(もちろん、不自然な例は、forループ優雅で不要となる。)

+0

これらのいずれの場合も影にする必要はありません。 – Rick

+1

@Rick誰もそれが必要であると話していませんでした。陰影は必要ありません。 –

+0

私は、誰も影にしてはいけないと言っています。変数に異なる名前を付けるだけです。 – Rick