第VI章 アクセス制御(上)
アクセス制御の最初の実装、および関連は適切ではありません。
クラスライブラリの開発者はコードや改善点を変更する権限を持っており、クライアントコードは、これらの変更によって影響されないことを保証しなければなりません。この目標は合意することによって達成することができますが、プログラム開発者が古いを達成するために、新たな実装を追加したい場合は、すべての変更は、そのライブラリの開発者は意志、クライアントのプログラマのコードのメンバーを損なう可能性があります支援の手と足は、何を変更することはできません。
この問題を解決するために、 Javaは使用できないクライアントプログラマーの開発ライブラリに使用できるかを指定するために、アクセス修飾子を提供します。アクセス制御レベルは、最大から最小の特権にした:パブリック、保護、パッケージアクセス(キーワードなし)、プライベート。
しかし、ライブラリコンポーネント制御の問題にアクセスする権利を持っている人のための会員図書館の概念だけでなく、コンポーネントが凝集クラスライブラリクラスライブラリユニットに同梱かの疑問がまだである、まだ不完全です。このために、のJava キーワードパッケージが制御し、かつによるクラスへの修飾子へのアクセスはまだ、同じパッケージ内に存在している影響を受けた別のパッケージに存在します。
6.1 パッケージ:ライブラリユニット
パッケージは、単一の名前空間の下で一緒に編成されているクラスのセットが含まれています。
例えば、中ジャワで編成されている標準のリリースのツールライブラリがありjava.utilの名前空間の下には。java.utilでは、呼び出したのArrayList 使用してクラスをArrayListの一つの方法は、その完全な名前を使用することであるjava.util.ArrayListの指定を。
パブリック クラスFullQualification { 公共 静的 ボイドメイン(文字列[]引数){ java.util.ArrayListのリスト = 新しいjava.util.ArrayListの()。 } }
これはすぐにプログラムが非常に長くなってみましょう、私たちは使用インポートキーワードを:
輸入はjava.util.ArrayList; パブリック クラスSingleImport { 公共 静的 ボイドメイン(文字列[]引数){ ArrayListのリスト = 新しいArrayListを()。 } }
今、あなたはの使用を制限することができないのArrayListを「およびすべてのクラスをインポートするために、ここでのみ使用する必要があります* :」
輸入java.utilの。*;
私たちはインポートしたい理由のすべてのクラスのメンバーの名前は、互いに分離されている、名前を管理するための仕組みを提供することで、クラスメソッドF()とBのクラスメソッドの同じパラメータリスト持っているf()がお互いにしません競合。しかし、クラス名の競合はどのように行うには?ではJavaのネームスペースの完全な制御と、各クラスの組み合わせに対して一意の識別子を作成するには、非常に重要なものとなっています。
書くときのJavaにソースコードファイルを、このファイルは通常、単位(翻訳単位)をコードと呼ばれ、各コンパイル単位はサフィックス持っている必要があります.javaファイルを、とにコンパイル単位を持つことができる公共のクラス、クラス名前は(大文字と小文字を含む)ファイルの名前と同じでなければなりません。各コンパイル単位は一つだけ持つことができますパブリッククラス、またはコンパイラは受け付けません。
6.1.1 コードの組織
コンパイルするときの.java ファイルを、中の.java 各クラスの出力ファイル内のファイルを持っています、として、出力ファイルの名前の.java 各クラスのファイル名は同じですが、拡張子付きの.class 、そのため、コンパイル時に少量の.java ファイルの後には、たくさんのでしょうの.class ファイルを。Javaのグループがプログラムを実行することができますにパッケージ化して圧縮することができるのJava ドキュメントファイル(JAR の)の.class ファイルは、のJava インタプリタは、これらのファイルを見つけるための責任がある、と解釈してインストールされています。
ライブラリは、実際にクラスファイルのセットで、各ファイルが持っている公共のクラスを、そして非任意の数のパブリックグループに属するこれらのメンバーを必要に応じてクラスは、各ファイルは、メンバーには、キーを使用することができました単語のためのパッケージ変更。
使用パッケージ文を、それが事故の最初の文に加えて、ファイルのコードのコメントにする必要があり、ファイルの先頭に書きました:
パッケージアクセス。
声明の中で、あなたがコンパイル単位が呼び出されていることを示すためにアクセスライブラリの一部。ファイル名があると仮定するとMyClass.java 、それがファイル内にある、唯一のことを意味し、パブリッククラスのクラス名でなければなりませんMyClassの。
パッケージaccess.mypackage。 パブリック クラスMyClassの{ // ... }
心に留めておくために、ライブラリのデザイナーとして、パッケージに違約金と輸入のキーワードは、人々が使用してどのように多くの関係なくなるように、あなたが分離ゾンビ単一グローバルネームスペースを行うことができ、インターネットとJavaはクラスを書き始める、名前が競合の問題には表示されません。
6.1.2 独自のパッケージ名を作成します
決して本当にシステム単一のファイルにパックのパッケージをパッケージ化され、パッケージは、多くの構成が可能仏ので .classファイルの設定ファイル、その後、状況は少し複雑です。起きてからこれを避けるために、論理的な方法は、すべての特定のパッケージ化することであるの.class ディレクトリ内のファイルを、それがこの問題を解決するために、オペレーティング・システムの階層的なファイル構造を使用することです。
収入のサブディレクトリ内のすべてのファイルは、他の二つの問題を解決することができます。一意の名前を作成する方法?どのようにクラスのディレクトリ構造にどこかに隠されて見つけることができます。これらのタスクはでているの.class へのファイルパスコード化されたパッケージ名を達成するために。
Javaは、次のようにインタプリタを実行しています:
まず、環境変数を見つける CLASSPATHを、CLASSPATHは、オペレーティングシステムによって設定することができ、見つけるために使用される1つのまたは複数のディレクトリが含まの.class ファイルのルートディレクトリを。ルートディレクトリから開始し、インタプリタの名前は、パッケージを取得してから、バックスラッシュに各ドットを交換CLASSPATH ルートのパス名を生成し、経路を用いて得られるであろうCLASSPATH それぞれ異なる項目に接続され、インタプリタでこれらのディレクトリは、作成するクラスに関連付けられている名前見つけるための.class ファイルを。
紛争:
もし形で導入すると同時に、「*」と同じ名前を含む2つのライブラリー:
輸入net.mindview.simple *。;
輸入java.utilの。*;
由于两个类都含有Vector类,这样就存在潜在的冲突。如果现在要创建一个Vector类的话就会产生冲突:
Vector v = new Vector();
这到底是取用那个Vector类呢?编译器不知道,于是编译器就会提出错误信息,强制你明确指明:
java.util.Vector v = new java.util.Vector();
由于这样可以完全指明该Vector类的位置,所以除非还要使用import java.util中的其他东西,否则没有必要写import java.util.*语句了。
6.1.3 定制工具库
现在我们可以创建自己的工具库,例如我们已经用到的System.out.println()的别名可以减少输出负担,这种机制可以用于名为Print的类中,这样我们在使用该类的时候可以用一个更具可读性的静态import语句来导入:
package com.example.demo; import java.io.*; public class Print { public static void print(Object obj) { System.out.println(obj); } public static void print() { System.out.println(); } public static void printnb(Object obj) { System.out.print(obj); } public static PrintStream print(String format, Object... args) { return System.out.printf(format, args); } }
现在,你可以创建有空的工具,并将其添加到自己的类库中。
6.1.4 用import改变行为
Java没有C的条件编译功能,该功能可以使你不必更改任何程序代码,就能切换开关并产生不同的行为。然而条件编译还有其他一些有价值的用途,例如说调试。调试功能在开发过程中是开启的,而在发布的产品中是禁用的。
6.1.5 对使用包的忠告
无论何时创建包,都已经在给定包名的时候隐含地指定了目录结构,这个包必须位于其名称所指定的目录之中,而该目录必须是在以CLASSPATH开始的目录中可以查询到的。