Effective Java第22条:静的メンバー類を優先的に考慮する

3353 ワード

ネスト類とは、他のクラスの内部に定義されているクラスのことです。ネスト類が存在する目的はその周辺類にサービスを提供することです。入れ子類が将来他の環境で使用される可能性があるなら、トップクラスであるべきです。ネスト類は4種類あります。スタティックメンバー類、スタティックメンバー類、ノンスタティックメンバー類、匿名類(anonymous class)、ローカル類(local class)。第一種類以外の3つは内部類と呼ばれています。
    静的なメンバークラスは最も簡単なネストタイプです。それを普通のクラスと見なしたほうがいいです。たまたま他のクラスの内部に声明されただけです。周辺のすべてのメンバーにアクセスできます。これらの声明をプライベートのメンバーとして含みます。静的なメンバクラスは、外周類の静的なメンバであり、他の静的なメンバと同様に、同様のアクセス可能なルールを遵守する。プライベートとして宣言されている場合は、周辺の内部だけでアクセスできます。
        静的なメンバ類の一般的な使用は、公有の補助的なクラスとして、外部のクラスと一緒に使用する場合にのみ意味があります。
   文法的には、静的なメンバタイプと非静的なメンバタイプとの間の唯一の違いは、静的なメンバタイプの声明には修飾子staticが含まれていることである。彼らの文法は非常に似ていますが、この二つの入れ子類は大きく違っています。非静的なメンバタイプの各例は、外周タイプの外周例に関連して暗黙的に含まれる。非静的なメンバクラスの例示的な方法の内部では、周辺インスタンス上の方法を呼び出すことができ、または修正されたthis構造を利用して周辺インスタンスの参照を得ることができる。ネストクラスの例が周辺クラスのインスタンス以外に独立して存在する場合、このネストクラスは静的なメンバクラスでなければならない。外周インスタンスがない場合、非静的なメンバクラスを作成することは不可能である。
   非静的なメンバクラスのインスタンスが作成されると、それと周辺のインスタンスとの関連関係も確立される。また、この関連関係は今後も修正されません。一般的に、このような管理は、外周のある例示的な方法の内部に非静的なメンバ類のコンストラクタが呼び出されると自動的に確立される。この関係はエンクロージングInstance.new Member Classを使って手で作ることも可能ですが、あまり使われていません。このような関連は、予想されるように、非静的なメンバクラスの実例的な空間を消費し、構造の時間的オーバヘッドを増加させる必要がある。
   非静的なメンバ類の一般的な使用法は、外部クラスのインスタンスが別のタイプのインスタンスとして見なされることを可能にするAdapterを定義するものである。例えば、Mapインターフェースの実装は、MapのkeySet、entrySet、Values方法によって返される非静的なメンバタイプを使用して、それらのセットビューを実現することが多い。同様に、SetおよびListのような集合インターフェースの実現は、しばしば非静的なメンバークラスを用いて、彼らのサブエージェントを実現することでもある。
  
//Typical use of a nonstatic member class
public class MySet<E> extends AbstractSet<E>
{
	public Iterator<E> iterator()
	{
		return new MyIterator();
	}
	
	private class MyIterator implements Iterator<E>
	{
		
	}
}
   ステートメントのメンバーが周辺のインスタンスにアクセスすることを要求しない場合は、常にstatic修飾子をその生命の中に置いて、静的なメンバークラスではなく、静的なメンバークラスにします。static修飾子が省略されている場合、各インスタンスは、追加の外周オブジェクトへの参照を含む。この引用を保存するには時間と空間が必要であり、周辺の例はゴミ回収に適合した時に保留されることになる。周辺例がない場合には、インスタンスの割り当ても必要であり、非静的なメンバクラスは使用できない。なぜなら、非静的なメンバクラスのインスタンスは、周辺のインスタンスが必要であるからである。
   プライベート静的メンバクラスの一般的な使用法は、周辺クラスによって代表されるオブジェクトのコンポーネントを表すために使用される。
   匿名クラスはJavaプログラミング言語の他の任意の構文ユニットとは異なります。あなたが想像しているように、匿名には名前がありません。外郭のメンバーではありません。それは他のメンバーと一緒に声明されているのではなく、使用しながら声明と実用化されています。匿名クラスは、コード内の任意の場所に存在することができます。匿名クラスが非静的環境に出現する場合にのみ、周辺インスタンスが存在する。しかし、それらが静的環境に現れても、任意の静的メンバーを持つことはできない。
   匿名系の適用性は多くの制約を受ける。それらが声明されている時以外は、それらを具体化することはできません。instance ofテストを実行できないか、または名前が必要な種類の他のことをしてもいいです。複数のインターフェースを実現するために匿名クラスを宣言できないか、またはクラスを拡張し、クラスを拡張し、インターフェースを実現します。匿名クラスのクライアントは、その超タイプから継承される以外は、任意のメンバーを呼び出すことができません。匿名のクラスが式に現れるため、それらは短くしなければなりません。約10行以上でなければ、プログラムの可読性に影響を与えます。
   匿名系の一般的な使い方は、動的な関数オブジェクト作成(function oject、21条参照)です。例えば、21条のArays.sort方法で呼び出し、匿名のCompratorの例を用いて、文字列の長さのセットに従って並べ替えを行う。匿名クラスの別の一般的な使用法は、Runnable、ThreadまたはTimeTaskのようなプロセスオブジェクトを作成することである。第三の一般的な用法は静的工場内部にある(第18条中国i部分のintArayAssList法を参照)。
   局部類は四種類の入れ子類の中で一番少ない種類です。任意の「局所変数を宣言することができる」ところでは、局部類を宣言することができ、また、部分類も同様の作用域規則を遵守することができます。局部類と他の3種類の入れ子類のそれぞれにはいくつかの共通の属性があります。メンバークラスと同じように、一部に名前があり、重複して使用することができます。匿名クラスと同様に、当局部類が実際に非静的環境で定義されている場合のみ、周辺例があり、静的メンバーも含まれない。匿名クラスと同様に、読み取り可能性に影響を与えないように短くしなければならない。
   簡単に言えば、四つの種類の嵌合類があります。それぞれ自分の用途があります。もし一つのネスト類が単一の方法以外でまだ見られている必要があるなら、あるいはそれは長すぎて、方法の内部に置くのに適しないなら、メンバークラスを使うべきです。メンバークラスの各例が周辺インスタンスへの参照を必要とする場合、メンバークラスを非静的に構成する。そうでないと静的になります。このネスト類は一つの方法の内部に属すると仮定して、一箇所でインスタンスを作成する必要があるだけで、予め設定したタイプがこのタイプの特徴を説明してもいいです。匿名クラスにします。そうしないと、局部類になります。