2012-01-23 12 views
25

私は静的コンテキストでもスコープ内の同じ名前のメソッドすべてをJava非静的メソッドで上書きすることを実験によって確認しました。パラメータのオーバーロードを許可しなくても。 LikeJava静的インポート

import java.util.Arrays;  
import static java.util.Arrays.toString; 

public class A { 
    public static void bar(Object... args) { 
     Arrays.toString(args); 
     toString(args);  //toString() in java.lang.Object cannot be applied to (java.lang.Object[]) 
    } 
} 

これについては何も見つかりません。これはバグですか?そうでない場合は、そのような言語を実装する理由はありますか?

UPD:Java 6はこの例をコンパイルしません。質問は - なぜですか?

+0

それはスーパーオブジェクトの 'toString()' –

+2

IMHOを参照しているようですが、静的インポート機能全体が悪い概念であり、名前空間を汚染し、コードの読みやすさを混乱させます。怠け者ではない、静的関数の囲むクラス/インタフェースをタイプするのはそれほど難しいことではないが、私たちはそのためのIDEを持っている。静的なインポートを使用しないようにしてください。 – buc

+0

@ジーガー・ジョシ、そうだね。しかし、私は何かを見つけることはできません。さらに、私たちは静的コンテキストから 'Object.toString'を呼び出すことができないので、この振る舞いではロジックが表示されません。 –

答えて

21

説明は簡単です右の名前の。それでは、過負荷解決やゲーム内でのコラボレーションのようなものが来るだけです。

ここでは、toString()メソッドを含む最小の囲みスコープがクラスAであり、Objectから継承しています。したがって、私たちはそこで止まり、遠くには検索しません。残念ながら、コンパイラは、指定されたスコープ内のメソッドの最適な適合を見つけようとし、それらを呼び出すことができず、エラーを通知します。スコープ内に自然にある方法は、静的な輸入品よりも優先されるためを静的に、オブジェクトのメソッドと同じです名前のメソッドをインポートすることはありません(JLSを詳細にメソッドのシャドーイングを説明していますが、このために意味

私はそれを覚えておく方がずっと簡単だと思う)。

編集:@alfは、画像全体を望む人のためにdescribes the method invocationというJLSの正しい部分を親切に提出しました。それはむしろ複雑ですが、問題は単純ではないので、それが期待されます。

+4

JLSリンク(必要な場合) - http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.1 – alf

+0

@alfありがとうございます。 。私はJLSでそれについての説明をどこで見つけるかを知っていれば自分で追加していただろう。 – Voo

4

オーバーライドではありません。正常に処理された場合は、this.toString()Arrays.toStringの代わりにAのメソッドにアクセスします。

シャドウNという名前のフィールドをインポートパッケージPのコンパイルユニットCにおける単一静的インポート宣言D:

language specification

は、静的インポートのみ static方法及び種類の解像度に影響を与えることを説明しますcの中のcの静的インポート・オンデマンド宣言によってインポートされたnという静的フィールドの宣言。

署名付きのnという名前のメソッドをインポートするパッケージpのコンパイル単位cの単一静的インポート宣言dは、という静的メソッドの宣言をシャドウします.nは、static-import-オンデマンド宣言、c。

N名前型の宣言を影をインポートパッケージPのコンパイルユニットCにおける単一静的インポート宣言D:

  • 静的インポートによりN命名インポート任意スタティック型 cの - オンデマンド宣言。
  • トップレベル型(§7.6)nの名前は、別のコンパイル単位(§7.3)で宣言されています。
  • 任意タイプnは、タイプイン・オン・デマンド宣言(7.5.2項)によってインポートされます。全体を通して

静的インポートは、非静的メソッドまたは内部タイプをシャドウしません。

したがって、toStringは非静的メソッドをシャドーしません。 toStringAの非静的メソッドを参照できるため、staticメソッドがArraysであるため、toStringというメソッドがString toString()というスコープ内で使用可能なtoStringという唯一のメソッドにバインドされます。そのメソッドは引数を取ることができないため、コンパイルエラーが発生します。

Section 15.12.1は、メソッドの解決方法を説明しており、利用できないメソッド名をstaticメソッド内でシャドーイングできるように完全に書き直されている必要がありますが、memberメソッドではありません。

私は、言語設計者がメソッド解決規則を単純にしたいと思っています。これは、同じ名前がstaticメソッドに含まれているかどうかにかかわらず同じものを意味し、変更のみが利用可能です。

方法を解決するコンパイラがメソッドを持っている最小の囲みスコープを見つけているん最初に呼び出されるように:それは動作が非常に直感的であるという事実は変わりませんが、

+0

メソッド 'bar'が静的であることを除いて、編集した@StasKurilinの – chrisbunney

+0

に' toString() 'を呼び出すインスタンスはありません。 –

+2

@StasKurilin [par。 6.3.1](http://java.sun.com/docs/books/jls/third_edition/html/names.html#34133)に詳しく説明しています。これは、インスタンスメソッド 'Object.toString()'の宣言が、そのスコープ内の他のメソッド*をシャドウすることを示しています。これには、 'Arrays.toString(Object [])'の静的インポートが含まれます。これは、事実上、静的インポートは効果がないことを意味します。コンパイラはメソッド呼び出しを解決することさえ考慮しません。 – millimoose

0

通常のインポートとは異なるバグではないと思います。たとえば、通常のインポートの場合、インポートされたものと同じ名前のプライベートクラスがある場合、インポートされたものは反映されません。

1

あなたは似て探してコードを以下しようとした場合、あなた、これはコンパイルし、あなたがそのtoString()(またはで定義された他の方法ではありません

import static java.util.Arrays.sort; 
public class StaticImport { 
    public void bar(int... args) { 
     sort(args); // will call Array.sort 
    } 
} 

任意のコンパイラエラーを取得することはできません理由class Object)は、Objectがクラスの親であるため、Objectクラスにスコープされます。したがって、コンパイラがObjectクラスからこれらのメソッドのシグネチャを見つけると、コンパイラエラーが発生します。私の例では、オブジェクトクラスはsort(int[])メソッドを持たないので、コンパイラはそれをstatic importと正しく一致させます。