1

第一に、私はJavaの人間ではありませんが、表面上はインポートの動作と矛盾しているように見えるものに出くわしました。

ファイルがあり、このファイルにmain関数があり、クラスFooも定義したとします。これで、 Fooの別の実装もパッケージに存在します。機能で両方のバージョンを使用するとします。

パッケージからFooを明示的にインポートすることはできません。つまり、mypackage.Fooをインポートします。

これにより、ファイルでローカルに定義されたクラスとの競合が発生するため、コンパイル時にエラーが生成されます。

あなたができることは、パッケージ全体をインポートすることです。つまり、mypackageをインポートします。*;

これは機能し、完全修飾名を使用してFooにアクセスできます。単純な名前を使用すると、ローカルFooが使用されます。私が見る矛盾は、前者はエラーを生成しますが(クラスをインポートし、インポートの唯一の目的は完全修飾名ではなく単純な名前を使用できるようにすることです)、後者は警告を発生させないことです。

どちらの場合も警告が生成されると思います。つまり、2つの場所で定義されているため、間違ったクラスを使用している可能性があります。または、単純な名前の使用はインポートされたクラスではなく、ローカルで定義されたクラスに解決されるため、importステートメントは冗長です。 1。

だから私の質問は:それがこのように実装されている根本的な理由はありますか?

はい、それは外れ値のケースです、私はそれを理解しています。

4

4 に答える 4

9

mypackageをインポートしなくても、完全修飾名を使用してFooにアクセスできます。*;

警告について:危険なことは何も起こっていないと思います。あいまいなものは何も使用していません。

于 2009-05-13T08:45:42.020 に答える
3

上記の回答が示すように、インポートFooは他のパッケージの に関して事実上何もしません。インポートするかどうかに関係なく、短いクラス名を介してその他の Foo を参照することはできず、完全修飾クラス名を介して参照できます。

概念的には、import mypackage.*必ずしも「からすべてのクラスをインポートする」とは考えられませんmypackageが、おそらく「競合しないすべてのクラスをインポートする」と考えることができますmypackage。Sun のコンパイラの実装がどのようにそれを行うのかはわかりませんが、mypackage.Foo をワイルドカードの一部として一致させない (したがって、まったくインポートしない) ことは間違いなく決定でき、コードはどちらの方法でも同じように機能します。

インポートは、実際には、短いクラス名から完全修飾クラス名へのエイリアスを設定するだけです (たとえば、それを とDate解釈すると言いますjava.util.Date)。競合するクラスだけをインポートするなど、完全に冗長なことを行うと、警告が表示されることが予想されます。ただし、パッケージ全体を でプルしている場合*、コンパイラがクラス名の1つが衝突していると不平を言うのは間違っているように思えます。これは実際には非常に頻繁に発生し、99% 以上の場合は無害であるため、「オオカミ少年」症候群を引き起こし、これらの警告やその他の警告に注意を払う可能性が低くなります。彼らに砲撃されることに慣れてください。

ところで、 と の両方をインポートする場合java.util.*java.sql.*これは許可され、それ自体は警告にはなりません。Dateただし、 (ローカル パッケージにそのようなクラスがない) だけを参照しようとすると、名前があいまいなため、コンパイル エラーが発生します。

于 2009-05-13T09:17:16.087 に答える
1

import mypackage.* は、mypackage にある他のすべてのものに必要な場合があります。警告があった場合、それを完全に回避することは困難です。つまり、mypackage から使用する他のすべてのクラスなどを完全に修飾する必要があります。さらに悪いことに、mypackage のバージョン 1 に Foo が含まれていなかった場合を考えてみてください。競合がなく、警告を発行する理由がまったくありません。バージョン 2 には Foo が含まれていますが、もちろん、プログラムでアクセスしたい Foo ではありません。したがって、コンパイラが "import package.*" の競合について警告すると、"import package.*" の上位互換性が低下する可能性があります。

于 2009-05-13T09:16:04.607 に答える
1

"import p.*" は、"現在のファイルで名前解決できない場合は、パッケージ p で名前解決を試みる" という意味と考えることができます。コンパイラは、インポート ステートメントを確認した時点でpのすべてをインポートするわけではありません。代わりに、即時コンパイル単位で解決できない名前が見つかった場合、 p (および import ...* ステートメントで指定された他のパッケージ) を調べます。

于 2009-05-13T11:21:51.920 に答える