[英]Cannot instantiate generic data type in class
我有一个不可变的类,具有以下布局,
public final class A <T> {
private ArrayList<T> myList;
private A(){
myList = new ArrayList<T>();
}
public A<T> 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。
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 <T> {
private ArrayList<T> myList;
private A(){
myList = new ArrayList<T>();
}
public A<T> addData(Supplier<T> factory){
A newOb = // make a new list and instantiate using overloaded constructor
T newT = factory.get();
newOb.myList.add(newT);
return newOb;
}
.........
}
像这样使用它,例如:
A<Integer> a = new A<>();
a.addData( () -> new Integer(0) );
内置的无参数Supplier接口可以用作回调的包装器。
我寻找类似问题的解决方案。 这是我做的解决方案:
public final class ImmutableA<T> {
private ArrayList<T> myList;
private Class<T> clazz;
public static <E> ImmutableA<E> createEmpty(Class<E> clazz) {
return new ImmutableA<>(clazz);
}
private ImmutableA(Class<T> clazz) {
this.myList = new ArrayList<T>();
this.clazz = clazz;
}
public ImmutableA<T> addData(T t) {
ImmutableA<T> newOb = new ImmutableA<>(clazz);
try {
Constructor<T> 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<T> getMyList() {
return myList;
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
ImmutableA<String> 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());
}
}
希望这会对某人有所帮助。
在java语言中,泛型是通过擦除实现的,因此不可能实例化泛型类型。 此外,也无法通过一般类型的数组来等等。
我怎么能克服这个? 我想添加一个新的参数副本,该副本将传递给我的列表中的addData。
您可以尝试将Cloneable
接口用作类型绑定或添加您自己的类似接口。
您可以像这样使用clone()方法:
public final class A <T extends Cloneable> {
private ArrayList<T> myList;
private A(){
myList = new ArrayList<T>();
}
public A<T> addData(T t){
T newT = t.clone();
newOb.myList.add(newT);
return newOb;
}
.........
}
你可以得到T的类型
Type type = new TypeToken<T>(){}.getType();
然后得到一个T做的实例
type.getClass().newInstance();
完整的例子
public T foo() {
try {
return (T) type.getClass().newInstance();
} catch (Exception e) {
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.