汎用[タイプインスタンスを作成]

3068 ワード

public Class Erased<T>{
	private final int SIZE = 100;
	public static void f(Object arg){
		if(arg instanceof T){}	//	Error
		T var = new T();		// Error
		T[] array = new T[SIZE];	// Error
		T[] array = (T)new Object[SIZE];	// Unchecked warning
	}
}

 
Erased.JAvaでタイプインスタンスを作成することはできません.一部の理由は消去のためです.もう一部の理由は、コンパイラがTがデフォルト(パラメータなし)コンストラクタを持っていることを検証できないためです.Javaのソリューションは、ファクトリオブジェクトを渡し、新しいインスタンスを作成するために使用します.最も便利なファクトリオブジェクトはClassオブジェクトなので、タイプラベルを使用するとnewInstance()を使用してこのタイプの新しいオブジェクトを作成できます.
class ClassAsFactory<T>
{
	T x;
	public ClassAsFactory(Class<T> kind){
		try{
			x = kind.newInstance():
		}catch(Exception e){
			...	
		}
	}
}

class Employee{}

public class InstantiateGenericType
{
	public static void main(String[] args){
		ClassAsFactory<Employee> fe = 
			new ClassAsFactory<Employee>(Employee.class);

		try{
			ClassAsFactory<Integer> f1 = 
				new ClassAsFactory<Integer>(Integer.class);
		}catch(Exception e){
			...
		}
	}
}

 
コンパイルは可能ですが、デフォルトのコンストラクタがないため、ClassAsFactoryのために失敗します.このエラーはコンパイル期間中にキャプチャされたものではないので賛成できませんが、明示的なファクトリを使用することを提案し、そのタイプを制限し、このファクトリを実現したクラスしか受け入れられません.
interface Factory1<T>
{
	T create();
}

class Foo2<T>
{
	private T x;
	public <F extends Factory1<T>> Foo2(F factory){
		x = factory.create();
	}
}

class IntegerFactory implements Factory1<Integer>
{
	public Integer create(){
		return new Integer(0);
	}
}
class Widget
{
	public static class Factory implements Factory1<Widget>
	{
		public Widget create(){
			return new Widget();
		}
	}
}

public class FactoryConstrain
{
	public static void main(String[] args){
		new Foo2<Integer>(new IntegerFactory());
		new Foo2<Widget>(new Widget.Factory())
	}
}

 
これはClassを伝達する一種の変体で、2つの方式はすべて工場の対象を伝達して、Classはたまたま
組み込まれたファクトリオブジェクトは、上記の方法で明示的なファクトリオブジェクトを作成しましたが、コンパイラチェックを取得しました.
もう1つの方法はテンプレートメソッド設計モードでありget()はテンプレートメソッドでありcreate()はサブクラスである
に表示されます.
abstract class GenericWithCreate<T>
{
	final T element;
	GenericWithCreate(){
		element = create();
	}
	abstract T create();
}

class X{}

class Creator extends GenericWithCreate<X>
{
	x create(){
		return new X();
	}
	void f(){
		sysout(element.getClass().getSimpleName());
	}
}

public class CreatorGeneric
{
	public static void main(String[] args){
		Creator c = new Creator();
		c.f();
	}
}