回答:
唯一の問題は、ローカルの名前空間が乱雑になることです。たとえば、Swingアプリを作成しているためにが必要java.awt.Event
であり、会社のカレンダーシステムとインターフェースしているとしますcom.mycompany.calendar.Event
。ワイルドカードを使用して両方をインポートすると、次の3つのいずれかが発生します。
java.awt.Event
としcom.mycompany.calendar.Event
て、あなたもコンパイルすることはできませんので。.*
)が、それは間違ったものであり、コードが型を間違っていると主張している理由を理解するのに苦労しています。com.mycompany.calendar.Event
が、後でコードを追加すると、以前の有効なコードは突然コンパイルを停止します。すべてのインポートを明示的にリストすることの利点は、どのクラスを使用するつもりだったかが一目でわかるため、単純にコードの読み取りがはるかに簡単になることです。簡単な1回限りのことをしている場合は、特に問題はありませんが、将来のメンテナはそれ以外の場合は明確にしてくれることに感謝します。
スターインポートへの投票です。importステートメントは、クラスではなくパッケージをインポートすることを目的としています。パッケージ全体をインポートする方がずっときれいです。ここで特定された問題(java.sql.Date
vsなどjava.util.Date
)は、他の方法で簡単に修正でき、特定のインポートでは実際に対処されず、すべてのクラスでめちゃくちゃなインポートを正当化するものではありません。ソースファイルを開いて、100のインポートステートメントをページングする必要があること以外に当惑することはありません。
特定のインポートを行うと、リファクタリングがより困難になります。クラスを削除/名前変更する場合は、その特定のインポートをすべて削除する必要があります。同じパッケージ内の別のクラスに実装を切り替える場合、インポートを修正する必要があります。これらの追加の手順は自動化できますが、実際には生産性への影響はありません。
Eclipseがデフォルトでクラスのインポートを行わなかったとしても、誰もがスターインポートを実行することになります。申し訳ありませんが、特定のインポートを行う正当な理由はありません。
クラスの競合に対処する方法は次のとおりです。
import java.sql.*;
import java.util.*;
import java.sql.Date;
Foo
を使用し、IDEを使用せずにコードを読み取った場合(引数はIDEを使用する必要はないため)、どのパッケージFoo
からのものであるかをどのようにして知ることができますか??確かに、IDEを使用すると、IDEが教えてくれますが、あなたの全体的な主張は、私がコードなしでコードを読むことができるはずだということです。明示的な輸入のヘルプやってドキュメントをコード (ワイルドカード避けるための大きな理由)、そして、それは多くの可能性が高い私がすることがありますことだ読んで、私はできるだろうということよりも、IDEを使用せずに、コードを書く IDEを使用せずに、コードを。
私の記事を参照してくださいインポートオンデマンドは悪です
つまり、最大の問題は、インポートするパッケージにクラスが追加されると、コードが壊れる可能性があるということです。例えば:
import java.awt.*;
import java.util.*;
// ...
List list;
Java 1.1では、これで問題ありませんでした。リストはjava.awtで見つかり、競合はありませんでした。
次に、完全に機能するコードをチェックインし、1年後に誰かがそれを編集のために持ち出し、Java 1.2を使用しているとします。
Java 1.2は、Listという名前のインターフェースをjava.utilに追加しました。ブーム!紛争。完全に機能するコードは機能しなくなります。
これはEVIL言語の機能です。ありませんNOタイプがされているので、コードだけでコンパイルを停止する必要があることを理由追加パッケージには...
さらに、読者が使用している「Foo」を判別するのが難しくなります。
java.util.List
vs java.awt.List
はそれほど悪くはありませんが、クラス名がでConfiguration
、複数の依存ライブラリが最新のmavenリポジトリバージョンに追加したときに試してください。
Javaインポート文でワイルドカードを使用することは悪くありません。
できれいなコード、ロバートC.マーティンは、実際に長いインポートリストを避けるためにそれらを使用することをお勧めします。
ここに推奨事項があります:
J1:ワイルドカードを使用して長いインポートリストを回避する
パッケージから2つ以上のクラスを使用する場合は、パッケージ全体を
パッケージをインポートします。*;
インポートの長いリストは読者にとって困難です。80行のインポートでモジュールの上部を乱雑にしたくありません。むしろ、どのパッケージと共同作業するかについての簡潔なステートメントをインポートしたいのです。
特定のインポートはハードな依存関係ですが、ワイルドカードインポートはそうではありません。特定のクラスをインポートする場合は、そのクラスが存在している必要があります。ただし、ワイルドカードを使用してパッケージをインポートする場合、特定のクラスが存在する必要はありません。importステートメントは、名前を探すときにパッケージを検索パスに追加するだけです。そのため、そのようなインポートによって真の依存関係が作成されることはなく、したがって、それらはモジュールの結合を低く保つのに役立ちます。
特定のインポートの長いリストが役立つ場合があります。たとえば、レガシーコードを処理していて、モックとスタブを構築するために必要なクラスを見つけたい場合は、特定のインポートのリストをたどって、それらすべてのクラスの実際の修飾名を見つけて、適切なスタブを配置します。ただし、この特定のインポートの使用は非常にまれです。さらに、最近のほとんどのIDEでは、ワイルドカードを使用したインポートを1つのコマンドで特定のインポートのリストに変換できます。したがって、レガシーの場合でも、ワイルドカードをインポートすることをお勧めします。
ワイルドカードをインポートすると、名前の競合やあいまいさが生じる場合があります。同じ名前で2つのクラスが異なるパッケージにある場合、使用する場合は、具体的にインポートするか、少なくとも具体的に修飾する必要があります。これは厄介なことですが、ワイルドカードインポートを使用する方が一般的に特定のインポートよりも優れているため、まれです。
パフォーマンス:バイトコードは同じであるため、パフォーマンスへの影響はありません。ただし、コンパイルのオーバーヘッドが発生します。
コンパイル:私のマシンでは、何もインポートせずに空のクラスをコンパイルすると100ミリ秒かかりますが、java。*をインポートすると同じクラスに170ミリ秒かかります。
import java.*
何もインポートしません。なぜ違いが出るのでしょうか?
かなりの量のJavaを使用する私がこれまでに働いたほとんどの場所では、明示的なインポートがコーディング標準の一部となっています。私は時々、プロトタイピングを迅速に行うために*を使用し、コードを製品化するときにインポートリストを展開します(一部のIDEもこれを行います)。
以前のプロジェクトで、*-importsから特定のインポートに変更すると、コンパイル時間が半分(約10分から約5分)に短縮されることがわかりました。* -importを使用すると、コンパイラーは、リストされた各パッケージを検索して、使用したものと一致するクラスを探します。この時間は短くてもかまいませんが、大規模なプロジェクトでは合計になります。
* -importの副作用は、開発者が必要なものについて考えるのではなく、一般的なインポート行をコピーして貼り付けることでした。
コンパイラーが*を具象クラス名に自動的に置き換えるため、ランタイムへの影響はありません。.classファイルを逆コンパイルしても、は表示されませんimport ...*
。
パッケージ名のみを使用できるため、C#は常に *(暗黙的に)を使用しますusing
。クラス名を指定することはできません。Javaはc#の後に機能を導入します。(Javaは多くの面で非常に扱いにくいですが、このトピックを超えています)。
Intellij Ideaで「インポートの整理」を行うと、同じパッケージの複数のインポートが自動的に*に置き換えられます。オフにすることはできないため、これは必須の機能です(しきい値を増やすことはできます)。
承認された返信に記載されているケースは無効です。*がなくても、同じ問題が発生します。*を使用するかどうかに関係なく、コードにパッケージ名を指定する必要があります。
記録のために:インポートを追加するときは、依存関係も示しています。
ファイルの依存関係(同じ名前空間のクラスを除く)をすばやく確認できます。
最も重要なのは、インポートjava.awt.*
によってプログラムが将来のJavaバージョンと互換性を失う可能性があることです。
「ABC」という名前のクラスがあり、JDK 8を使用していて、をインポートするとしますjava.util.*
。さて、Java 9が出て、java.util
偶然にも "ABC"と呼ばれる新しいクラスがパッケージにあるとします。プログラムはJava 9でコンパイルされません。コンパイラーは、「ABC」という名前が自分のクラスか、の新しいクラスかを知らないためですjava.awt
。
java.awt
実際に使用するクラスから明示的にそれらのクラスのみをインポートする場合は、この問題は発生しません。
リソース:
Stream
Java 8のjava.utilでJavaに追加された新しいクラスの例として使用できます...
両側で行われたすべての有効なポイントの中で、ワイルドカードを回避する主な理由はわかりませんでした。コードを読んで、すべてのクラスが何であるかを直接知りたい、またはその定義が言語にないか、ファイル、それを見つける場所。複数のパッケージが*でインポートされる場合、私はそれらすべてを検索して、認識できないクラスを見つける必要があります。読みやすさは最高で、コードを読むためにIDEを必要としないことにも同意します。