次のような単一のステートメントを使用する方がはるかに便利でクリーンです
import java.awt.*;
個々のクラスの束をインポートするよりも
import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...
import
ステートメントでワイルドカードを使用することの何が問題になっていますか?
唯一の問題は、ローカルの名前空間が乱雑になることです。たとえば、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
vsjava.util.Date
など) は他の手段で簡単に修正できますが、特定のインポートによって実際に対処されるわけではありません。ソース ファイルを開いて、100 個のインポート ステートメントをページをめくらなければならないことほど当惑することはありません。
特定のインポートを行うと、リファクタリングがより困難になります。クラスを削除/名前変更する場合は、その特定のインポートをすべて削除する必要があります。実装を同じパッケージ内の別のクラスに切り替える場合は、インポートを修正する必要があります。これらの余分な手順は自動化できますが、実際には生産性を損なうだけで、実際には何のメリットもありません。
Eclipse がデフォルトで特定のクラスのインポートを行わなかった場合、誰もがスター インポートを行うことになります。申し訳ありませんが、特定のインポートを行う合理的な理由はありません。
クラスの競合に対処する方法は次のとおりです。
import java.sql.*;
import java.util.*;
import java.sql.Date;
私の記事「ImportonDemandisEvil 」をご覧ください。
つまり、最大の問題は、インポートするパッケージにクラスが追加されたときにコードが破損する可能性があることです。例えば:
import java.awt.*;
import java.util.*;
// ...
List list;
Java 1.1では、これは問題ありませんでした。リストはjava.awtで見つかり、競合はありませんでした。
ここで、完全に機能するコードをチェックインし、1年後に誰かがコードを取り出して編集し、Java1.2を使用しているとします。
Java 1.2は、Listという名前のインターフェースをjava.utilに追加しました。ブーム!対立。完全に機能するコードは機能しなくなります。
これはEVIL言語の機能です。型がパッケージに追加されたという理由だけでコードのコンパイルを停止する必要がある理由はありません...
さらに、読者がどの「Foo」を使用しているかを判断するのが難しくなります。
Java インポート ステートメントでワイルド カードを使用することは悪くありません。
Clean Codeの中で、Robert C. Martin は、長いインポート リストを避けるためにそれらを使用することを実際に推奨しています。
推奨事項は次のとおりです。
J1: ワイルドカードを使用して長いインポート リストを回避する
パッケージから 2 つ以上のクラスを使用する場合は、パッケージ全体を
パッケージをインポートします。*;
インポートの長いリストは、読者にとって気が遠くなるようなものです。モジュールの上部を 80 行のインポートで散らかしたくありません。むしろ、どのパッケージと連携するかについての簡潔なステートメントをインポートに記載したいと考えています。
特定のインポートは強い依存関係ですが、ワイルドカードのインポートはそうではありません。クラスを明示的にインポートする場合、そのクラスが存在する必要があります。ただし、ワイルドカードを使用してパッケージをインポートする場合、特定のクラスが存在する必要はありません。import ステートメントは、名前を探すときにパッケージを検索パスに追加するだけです。したがって、そのようなインポートによって真の依存関係は作成されないため、モジュールの結合を少なくするのに役立ちます。
特定のインポートの長いリストが役立つ場合があります。たとえば、レガシー コードを扱っていて、モックとスタブを作成する必要があるクラスを見つけたい場合は、特定のインポートのリストをたどって、それらすべてのクラスの真の修飾名を見つけてから、適切なスタブを配置します。ただし、特定のインポートに対するこの使用は非常にまれです。さらに、最近のほとんどの IDE では、ワイルドカードを使用したインポートを単一のコマンドで特定のインポートのリストに変換できます。そのため、従来のケースでも、ワイルドカードをインポートすることをお勧めします。
ワイルドカードのインポートは、名前の競合やあいまいさを引き起こすことがあります。名前が同じでパッケージが異なる 2 つのクラスは、具体的にインポートするか、少なくとも使用時に具体的に修飾する必要があります。これは厄介な場合がありますが、一般的にワイルドカード インポートを使用する方が特定のインポートよりも優れているため、非常にまれです。
名前空間が乱雑になり、あいまいなクラス名を完全に指定する必要があります。これが最も一般的に発生するのは、次の場合です。
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
また、すべての依存関係がファイルの先頭にリストされているため、依存関係を具体的にするのにも役立ちます。
かなりの量のJavaを使用する私が働いたほとんどの場所では、明示的なインポートがコーディング標準の一部になっています。私は今でも * を使用して簡単なプロトタイピングを行い、コードを製品化するときにインポート リストを展開します (一部の IDE ではこれも行われます)。
ファイル全体を見なくても、ファイルで使用されているすべての外部参照を確認できるため、特定のインポートを好みます。(はい、必ずしも完全修飾参照が表示されるとは限らないことはわかっています。しかし、可能な限りそれらを避けます。)
以前のプロジェクトで、*-imports から特定の imports に変更すると、コンパイル時間が半分 (約 10 分から約 5 分) に短縮されることがわかりました。*-import を指定すると、コンパイラはリストされた各パッケージを検索して、使用したクラスと一致するクラスを探します。この時間は短い場合もありますが、大規模なプロジェクトでは加算されます。
*-import の副次的影響は、開発者が必要なものを考えるのではなく、一般的なインポート行をコピー アンド ペーストすることでした。
実装のベースとなる開発技術が何であれ、 MODULES のリファクタリング作業を最小限に抑える方法を探してください。Java では、個々のクラスにインポートすることから逃れることはできませんが、パッケージは非常にまとまりのある単位であり、同時にパッケージ名を変更する労力を削減するという意図を反映して、少なくとも一度にパッケージ全体をインポートできます。
そして、それがローカル名前空間を乱雑にする場合、それはあなたのせいではありません-パッケージのサイズを非難してください。
コンパイラは自動的に * を具体的なクラス名に置き換えるため、ランタイムへの影響はありません。.class ファイルを逆コンパイルすると、import ...*
.
C#は常にusing
* (暗黙的に) を使用します。これは、パッケージ名のみを使用できるためです。クラス名を指定することはできません。Java は、C# の後に機能を導入します。(Java は多くの点で非常にトリッキーですが、このトピックの範囲を超えています)。
Intellij Idea では、「インポートの編成」を行うと、同じパッケージの複数のインポートが自動的に * に置き換えられます。オフにすることはできないため、これは必須の機能です (ただし、しきい値を上げることはできます)。
承認された返信に記載されているケースは無効です。* がなくても、同じ問題が発生します。* を使用するかどうかに関係なく、コードでパッケージ名を指定する必要があります。
両側で行われたすべての有効なポイントの中で、ワイルドカードを避ける主な理由を見つけられませんでした。コードを読んで、すべてのクラスが何であるかを直接知ることができるようにしたい、または定義が言語にない場合、またはファイル、それを見つける場所。複数のパッケージが * でインポートされている場合、すべてのパッケージを検索して、認識できないクラスを見つける必要があります。可読性は最高であり、コードを読むために IDE を必要としないことに同意します。
Oracle による Java チュートリアルではワイルド カード インポートが使用されているため、ワイルド カード インポートの使用は悪くありません。Oracle の Java 関係者が間違ったことをするとは思いません。
上記のプログラムは、ワイルド カード インポートを使用します。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
ここで他のプログラムを見ることができます: https://docs.oracle.com/javase/tutorial/uiswing/examples/components/ .