java 无法在类中实例化泛型数据类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12093541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot instantiate generic data type in class
提问by h4ck3d
I have an immutable class , with the following layout ,
我有一个不可变的类,具有以下布局,
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;
}
.........
}
The error that I get here is cannot instantiate type T
. Now , I think this is related to maybe type erasure
in Java.
我在这里得到的错误是cannot instantiate type T
. 现在,我认为这可能type erasure
与 Java 相关。
How can I overcome this ? I want to add a new copy of the argument that is being passed to addData into my list.
我怎样才能克服这个?我想将传递给 addData 的参数的新副本添加到我的列表中。
采纳答案by gkuzmin
In java language generics are implemented by erasure, so it is impossible to instantiate a generic type. Also it is impossible to instiate an array of generic type and so on.
在java语言中泛型是通过擦除实现的,所以不可能实例化一个泛型类型。也不可能建立一个泛型类型的数组等等。
How can I overcome this ? I want to add a new copy of the argument that is being passed to addData into my list.
我怎样才能克服这个?我想将传递给 addData 的参数的新副本添加到我的列表中。
You can try to use Cloneable
interface as a type bound or add your own similar interface.
您可以尝试将Cloneable
接口用作类型绑定或添加您自己的类似接口。
回答by Ransom Briggs
T newT = (T) t.getClass().newInstance() // assuming zero args constructor and you'll
// have to catch some reflection exceptions
回答by rustyx
In Java 8 you can pass a factory lambdawhich would create a new instance of the desired type:
在 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;
}
.........
}
Use it like this for example:
例如,像这样使用它:
A<Integer> a = new A<>();
a.addData( () -> new Integer(0) );
The built-in no-argument Supplierinterface can be used as the wrapper for the callback.
内置的无参数供应商接口可用作回调的包装器。
回答by Vitaly
I looked for solution of similar problem. Here is the solution I made:
我寻找类似问题的解决方案。这是我提出的解决方案:
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());
}
}
}
Hope this will help to somebody.
希望这会对某人有所帮助。
回答by jolivier
You can use clone() method like this:
您可以像这样使用 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;
}
.........
}
回答by Luca Corradi
you can get the type of T doing
你可以得到 T 的类型
Type type = new TypeToken<T>(){}.getType();
then get an instance of T doing
然后得到一个 T 的实例做
type.getClass().newInstance();
Complete example
完整示例
public T foo() {
try {
return (T) type.getClass().newInstance();
} catch (Exception e) {
return null;
}
}