0

次のインポート ステートメントを検討してください。

java.io.* をインポートします。// わかる

import javax.servlet.*;

import javax.servlet.http.*;

「import javax.servlet .;」を含めたようなものではないでしょうか。したがって、「import javax.servlet.http. ;」という他の import ステートメントも自動的に含まれます。

「import javax.servlet.http.*」が http に対して明示的に定義されているのはなぜですか?

明確にして、私が間違っているかどうか教えてください。

4

3 に答える 3

1

はい、パッケージごとにワイルドカード インポートを行う必要があります。

なんで?JLSに関する限り、「com.example」と「com.example.pkg」は無関係のパッケージです。サブパッケージの概念は JLS で言及されていますが、関連するセマンティックはありません。特に「アクセス」ルールにはありません。 JLS 7.1は次のように述べています。

「パッケージの階層的な命名構造は、従来の方法で関連するパッケージを整理するのに便利であることを目的としていますが、トップレベルの型と同じ単純な名前を持つサブパッケージを持つパッケージを禁止すること以外には意味がありません (§7.6 ) そのパッケージで宣言されています。

たとえば、 という名前のパッケージと という名前oliverの別のパッケージoliver.twistの間、または とevelyn.woodという名前のパッケージの間に特別なアクセス関係はありませんevelyn.waugh。つまり、という名前のパッケージ内のコードは、他のパッケージ内のコードよりも、oliver.twistパッケージ内で宣言された型にうまくアクセスできません。」oliver

(そして、関連のない多数のパッケージのインポートを許可する構造は、悪い結果をもたらします...以下を参照してください。)

しかし、なぜ?それが言語の設計方法だからです。

しかし、なぜ?Java 言語の設計チームに、設計に関する決定が下された 1990 年代初頭に彼らがどのような考えを持っていたかを尋ねる必要があります。


しかし、複数パッケージのワイルドカード インポートがあった場合に何が起こるかを確認できるかもしれません。

非常に一般的なパターンであるこのパッケージ構造を考えてみましょう。

  com.example.weazellib - contains the public API classes for the library
  com.example.weazellib.impl - contains implementation classes that 
                               shouldn't be used by external clients

プログラマーが怠け者であることはよく知られている事実です (多くの人はそうです)。

  import com.example.weazellib.**    // hypothetical syntax

彼/彼女は、このクラス名前空間に外部 API クラスと内部クラスの両方を持つことになり、誤って内部クラスへの依存関係を作成しやすくなります。

(そして、「内部クラスのパッケージをプライベートにする」と言う前に...それは機能しません。のクラスcom.example.weazellibを使用できるようにする必要があるクラスが にありcom.example.weazellib.implます。後者がパッケージをプライベートにした場合、前者はできません。それらを使用します。)

対照的に、Java にパッケージ「ツリー」をインポートするワイルドカードがない世界では、誤ってそれを行うことはできません。意図的implにパッケージをインポートする必要があります。これは良いことであり、複数のパッケージに対してワイルドカード インポートを記述することの「不便さ」よりもはるかに重要です。


もう 1 つの問題は、ワイルドカード インポートは長期的なソース コードの安定性に適しておらず、スーパー ワイルドカードを使用するとさらに悪化することです。

プログラマーが と の両方をインポートすることcom.example.weazellibcom.example.weazellib.impl彼のコードで行うべき正しいことであると判断し、スーパーワイルドカードを使用して両方をインポートするとします。com.example.weazellib.impl.ToesImplそして、彼が... asを使用するコードを書いたとしますToesImpl

com.example.weazellib.impl2ここで、"weazellib" 開発者が代替実装クラスを含む3 番目のパッケージを追加するとどうなるかを考えてみてくださいimpl。たとえば、次のようなクラスがあります。

com.example.weazellib.impl.ToesImpl
com.example.weazellib.impl2.ToesImpl

何が起こるのですか?さて、プログラマーのコードにはコンパイルエラーがあります。 ToesImplあいまいです...以前は存在しなかったパッケージからクラス名を取得するスーパーワイルドカードインポートの影響のためです。

通常のワイルドカード インポートにも同じ問題が存在することに注意してください。多くの人がワイルドカード インポートを使用しないのはそのためです。しかし、スーパーワイルドカードが問題をさらに悪化させることは間違いありません。

于 2013-04-07T00:22:08.713 に答える
0

インポートがどのように機能するかは、仕様で定義されています。

Java 言語仕様を参照してください

その理由は、javax.servlet と javax.servlet.http は別のパッケージであり、 import * はパッケージ メンバーを取り込むだけです。

また、コードが読みにくくなるため、ワイルド カード インポートはお勧めできません。

于 2013-04-07T00:01:02.077 に答える