508

次のような単一のステートメントを使用する方がはるかに便利でクリーンです

import java.awt.*;

個々のクラスの束をインポートするよりも

import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...

importステートメントでワイルドカードを使用することの何が問題になっていますか?

4

18 に答える 18

639

唯一の問題は、ローカルの名前空間が乱雑になることです。たとえば、Swing アプリを作成していて、 が必要java.awt.Eventであり、 を備えた会社のカレンダー システムともインターフェイスしているとしますcom.mycompany.calendar.Event。ワイルドカード方式を使用して両方をインポートすると、次の 3 つのいずれかが発生します。

  1. java.awt.Eventとの間に完全な名前の競合があるcom.mycompany.calendar.Eventため、コンパイルすることさえできません。
  2. 実際には 1 つしかインポートできませんが (2 つのインポートのうち 1 つだけがインポートされます.*)、それは間違ったものであり、コードがタイプが間違っていると主張している理由を理解するのに苦労しています。
  3. コードをコンパイルすると はありませんcom.mycompany.calendar.Eventが、後で追加すると、以前は有効だったコードが突然コンパイルを停止します。

すべてのインポートを明示的にリストすることの利点は、どのクラスを使用するつもりだったかが一目でわかることです。これにより、コードが非常に読みやすくなります。1 回限りの簡単な作業を行っているだけであれば、特に問題はありません、将来のメンテナーは、明確にしてくれたことに感謝するでしょう。

于 2008-09-29T03:58:50.553 に答える
228

スター輸入品の投票はこちら。import ステートメントは、クラスではなくパッケージをインポートすることを目的としています。パッケージ全体をインポートする方がはるかにクリーンです。ここで特定された問題 ( java.sql.Datevsjava.util.Dateなど) は他の手段で簡単に修正できますが、特定のインポートによって実際に対処されるわけではありません。ソース ファイルを開いて、100 個のインポート ステートメントをページをめくらなければならないことほど当惑することはありません。

特定のインポートを行うと、リファクタリングがより困難になります。クラスを削除/名前変更する場合は、その特定のインポートをすべて削除する必要があります。実装を同じパッケージ内の別のクラスに切り替える場合は、インポートを修正する必要があります。これらの余分な手順は自動化できますが、実際には生産性を損なうだけで、実際には何のメリットもありません。

Eclipse がデフォルトで特定のクラスのインポートを行わなかった場合、誰もがスター インポートを行うことになります。申し訳ありませんが、特定のインポートを行う合理的な理由はありません。

クラスの競合に対処する方法は次のとおりです。

import java.sql.*;
import java.util.*;
import java.sql.Date;
于 2008-09-29T15:45:56.250 に答える
201

私の記事「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」を使用しているかを判断するのが難しくなります。

于 2008-09-29T19:42:46.867 に答える
79

Java インポート ステートメントでワイルド カードを使用することは悪くありません。

Clean Codeの中で、Robert C. Martin は、長いインポート リストを避けるためにそれらを使用することを実際に推奨しています。

推奨事項は次のとおりです。

J1: ワイルドカードを使用して長いインポート リストを回避する

パッケージから 2 つ以上のクラスを使用する場合は、パッケージ全体を

パッケージをインポートします。*;

インポートの長いリストは、読者にとって気が遠くなるようなものです。モジュールの上部を 80 行のインポートで散らかしたくありません。むしろ、どのパッケージと連携するかについての簡潔なステートメントをインポートに記載したいと考えています。

特定のインポートは強い依存関係ですが、ワイルドカードのインポートはそうではありません。クラスを明示的にインポートする場合、そのクラスが存在する必要があります。ただし、ワイルドカードを使用してパッケージをインポートする場合、特定のクラスが存在する必要はありません。import ステートメントは、名前を探すときにパッケージを検索パスに追加するだけです。したがって、そのようなインポートによって真の依存関係は作成されないため、モジュールの結合を少なくするのに役立ちます。

特定のインポートの長いリストが役立つ場合があります。たとえば、レガシー コードを扱っていて、モックとスタブを作成する必要があるクラスを見つけたい場合は、特定のインポートのリストをたどって、それらすべてのクラスの真の修飾名を見つけてから、適切なスタブを配置します。ただし、特定のインポートに対するこの使用は非常にまれです。さらに、最近のほとんどの IDE では、ワイルドカードを使用したインポートを単一のコマンドで特定のインポートのリストに変換できます。そのため、従来のケースでも、ワイルドカードをインポートすることをお勧めします。

ワイルドカードのインポートは、名前の競合やあいまいさを引き起こすことがあります。名前が同じでパッケージが異なる 2 つのクラスは、具体的にインポートするか、少なくとも使用時に具体的に修飾する必要があります。これは厄介な場合がありますが、一般的にワイルドカード インポートを使用する方が特定のインポートよりも優れているため、非常にまれです。

于 2010-01-02T20:17:19.890 に答える
26

名前空間が乱雑になり、あいまいなクラス名を完全に指定する必要があります。これが最も一般的に発生するのは、次の場合です。

import java.util.*;
import java.awt.*;

...
List blah; // Ambiguous, needs to be qualified.

また、すべての依存関係がファイルの先頭にリストされているため、依存関係を具体的にするのにも役立ちます。

于 2008-09-29T04:05:04.873 に答える
22
  1. クラス名の競合 (異なるパッケージ内に同じ名前を持つ 2 つのクラス) を特定するのに役立ちます。これは * インポートでマスクできます。
  2. 依存関係が明示されるため、後でコードを読む必要がある人は、何をインポートするつもりで、何をインポートするつもりがなかったのかがわかります。
  3. コンパイラは依存関係を特定するためにパッケージ全体を検索する必要がないため、一部のコンパイルを高速化できますが、これは通常、最新のコンパイラでは大したことではありません。
  4. 明示的なインポートの不便な側面は、最新の IDE で最小限に抑えられています。ほとんどの IDE では、邪魔にならないようにインポート セクションを折りたたむことができ、必要に応じてインポートを自動的に入力し、未使用のインポートを自動的に識別してクリーンアップすることができます。

かなりの量のJavaを使用する私が働いたほとんどの場所では、明示的なインポートがコーディング標準の一部になっています。私は今でも * を使用して簡単なプロトタイピングを行い、コードを製品化するときにインポート リストを展開します (一部の IDE ではこれも行われます)。

于 2008-09-29T04:42:24.847 に答える
11

ファイル全体を見なくても、ファイルで使用されているすべての外部参照を確認できるため、特定のインポートを好みます。(はい、必ずしも完全修飾参照が表示されるとは限らないことはわかっています。しかし、可能な限りそれらを避けます。)

于 2008-09-29T03:59:11.813 に答える
10

以前のプロジェクトで、*-imports から特定の imports に変更すると、コンパイル時間が半分 (約 10 分から約 5 分) に短縮されることがわかりました。*-import を指定すると、コンパイラはリストされた各パッケージを検索して、使用したクラスと一致するクラスを探します。この時間は短い場合もありますが、大規模なプロジェクトでは加算されます。

*-import の副次的影響は、開発者が必要なものを考えるのではなく、一般的なインポート行をコピー アンド ペーストすることでした。

于 2008-10-10T15:57:56.600 に答える
6

DDDの本

実装のベースとなる開発技術が何であれ、 MODULES のリファクタリング作業を最小限に抑える方法を探してください。Java では、個々のクラスにインポートすることから逃れることはできませんが、パッケージは非常にまとまりのある単位であり、同時にパッケージ名を変更する労力を削減するという意図を反映して、少なくとも一度にパッケージ全体をインポートできます。

そして、それがローカル名前空間を乱雑にする場合、それはあなたのせいではありません-パッケージのサイズを非難してください。

于 2016-06-17T08:54:23.197 に答える
4
  • コンパイラは自動的に * を具体的なクラス名に置き換えるため、ランタイムへの影響はありません。.class ファイルを逆コンパイルすると、import ...*.

  • C#は常にusing* (暗黙的に) を使用します。これは、パッケージ名のみを使用できるためです。クラス名を指定することはできません。Java は、C# の後に機能を導入します。(Java は多くの点で非常にトリッキーですが、このトピックの範囲を超えています)。

  • Intellij Idea では、「インポートの編成」を行うと、同じパッケージの複数のインポートが自動的に * に置き換えられます。オフにすることはできないため、これは必須の機能です (ただし、しきい値を上げることはできます)。

  • 承認された返信に記載されているケースは無効です。* がなくても、同じ問題が発生します。* を使用するかどうかに関係なく、コードでパッケージ名を指定する必要があります。

于 2018-03-18T05:29:51.747 に答える
2

両側で行われたすべての有効なポイントの中で、ワイルドカードを避ける主な理由を見つけられませんでした。コードを読んで、すべてのクラスが何であるかを直接知ることができるようにしたい、または定義が言語にない場合、またはファイル、それを見つける場所。複数のパッケージが * でインポートされている場合、すべてのパッケージを検索して、認識できないクラスを見つける必要があります。可読性は最高であり、コードを読むために IDE を必要としないことに同意します。

于 2017-12-21T00:25:52.767 に答える
-1

Oracle による Java チュートリアルではワイルド カード インポートが使用されているため、ワイルド カード インポートの使用は悪くありません。Oracle の Java 関係者が間違ったことをするとは思いません。

こちらをご覧ください: https://docs.oracle.com/javase/tutorial/uiswing/examples/components/CustomComboBoxDemoProject/src/components/CustomComboBoxDemo.java

上記のプログラムは、ワイルド カード インポートを使用します。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

ここで他のプログラムを見ることができます: https://docs.oracle.com/javase/tutorial/uiswing/examples/components/ .

于 2021-12-16T13:44:16.607 に答える