在java中实例化泛型类型

时间:2012-05-31 09:27:56

标签: java templates generics object instantiation

我被困住了。来自C ++,我认为这只会起作用,但事实并非如此。你能给我一个建议吗?我将尽力在每个用于T的类中创建一种创建方法。

public class A<T>{

    private T t_;

    public A(){
        t_ = new T(); //error
    }

}  

此外,我不想让构造函数看起来像:A(Class classT){... 理想情况下,我希望有类似这个c ++代码的东西。

template<class T>
class A{
private:
   T t_;

public:
   A(){}

};

感谢您的帮助。

4 个答案:

答案 0 :(得分:11)

除了类型擦除的问题 - 这使得在任何情况下都不可能 - 你根本无法保证T有一个暴露的,无参数的构造函数!

传统的解决方法是传递工厂对象,它们提供可用于获取T个对象的方法。一个简单的例子是

interface Factory<T> {
  T create();
}

然后您的班级可以获得Factory<T>并在其上调用create()以获得更多T s。更复杂的示例可能需要create方法的其他参数,例如,或重载。

不太常见的解决方法包括显式反射,传递Class<T>个对象。例如,ArrayList.class.newInstance()返回新构造的原始ArrayList。您必须显式传递Class对象,并且基于反射的方法比普通构造函数或工厂对象慢(即使反射速度最近有所提高)。您还依赖于暴露无参数构造函数的类,但情况并非总是如此。它可以被用来工作,但它从来就不是我称之为“令人愉快的”。

(也就是说,作为参考,有迹象表明Java 8中的项目Lambda和朋友的情况可能会有所改变。)

答案 1 :(得分:7)

你不能用Java做这些事情。阅读类型擦除:http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

答案 2 :(得分:5)

很抱歉让你失望但是在没有构造函数的java中这简直是不可能的。

Java在运行时丢弃通用信息(参见类型擦除)

答案 3 :(得分:0)

试试这个:

private <E extends ISomething> E createInstance(Class<E> clazz) {
        E ret;
        try {
            ret = clazz.newInstance();
            ret.setSomething(something);

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return ret;
    }