无法在类中实例化通用数据类型
我有一个不可变的类,具有以下布局,
public final class A { private ArrayList myList; private A(){ myList = new ArrayList(); } public A addData(T t){ A newOb = // make a new list and instantiate using overloaded constructor T newT = new T(); ***********ERROR HERE************* newOb.myList.add(newT); return newOb; } ......... }
我在这里得到的错误是cannot instantiate type T
现在,我认为这与Java中的type erasure
有关。
我怎么能克服这个? 我想添加一个新的参数副本,该副本将传递给我的列表中的addData。
在java语言中,generics是通过擦除实现的,因此不可能实例化generics类型。 此外,也无法通过一般类型的数组等来实现。
我怎么能克服这个? 我想添加一个新的参数副本,该副本将传递给我的列表中的addData。
您可以尝试将Cloneable
接口用作类型绑定或添加您自己的类似接口。
T newT = (T) t.getClass().newInstance() // assuming zero args constructor and you'll // have to catch some reflection exceptions
在Java 8中,您可以传递工厂lambda ,它将创建所需类型的新实例:
public final class A { private ArrayList myList; private A(){ myList = new ArrayList (); } public A addData(Supplier factory){ A newOb = // make a new list and instantiate using overloaded constructor T newT = factory.get(); newOb.myList.add(newT); return newOb; } ......... }
像这样使用它,例如:
A a = new A<>(); a.addData( () -> new Integer(0) );
内置的无参数Supplier接口可以用作回调的包装器。
我寻找类似问题的解决方案。 这是我做的解决方案:
public final class ImmutableA { private ArrayList myList; private Class clazz; public static ImmutableA createEmpty(Class clazz) { return new ImmutableA<>(clazz); } private ImmutableA(Class clazz) { this.myList = new ArrayList (); this.clazz = clazz; } public ImmutableA addData(T t) { ImmutableA newOb = new ImmutableA<>(clazz); try { Constructor constructor = clazz.getDeclaredConstructor(clazz); T newT = constructor.newInstance(t); newOb.myList.add(newT); return newOb; } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return null; } public ArrayList getMyList() { return myList; } public static void main(String[] args) throws InstantiationException, IllegalAccessException { ImmutableA immutableA = createEmpty(String.class); System.out.print(immutableA.getMyList().toString()); immutableA = immutableA.addData("a"); System.out.print(immutableA.getMyList().toString()); immutableA = immutableA.addData("b"); System.out.print(immutableA.getMyList().toString()); immutableA = immutableA.addData("c"); System.out.print(immutableA.getMyList().toString()); }
}
希望这会对某人有所帮助。
您可以像这样使用clone()方法:
public final class A { private ArrayList myList; private A(){ myList = new ArrayList (); } public A addData(T t){ T newT = t.clone(); newOb.myList.add(newT); return newOb; } ......... }
你可以得到T的类型
Type type = new TypeToken(){}.getType();
然后得到一个T做的实例
type.getClass().newInstance();
完整的例子
public T foo() { try { return (T) type.getClass().newInstance(); } catch (Exception e) { return null; } }