汎用[タイプインスタンスを作成]
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
組み込まれたファクトリオブジェクトは、上記の方法で明示的なファクトリオブジェクトを作成しましたが、コンパイラチェックを取得しました.
もう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();
}
}