在Java中实例化通用类型

7

我卡住了。作为一个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(){}

};

感谢您的帮助。

可能是在Java中创建泛型类型的实例?的重复问题。 - pingw33n
你是对的。完全忽略了那个。 - nux
4个回答

10

除了类型擦除的问题 - 无论如何都不可能实现 - 您根本无法保证 T 具有公开的、无参数的构造函数!

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

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

然后你的类可以获取一个 Factory<T> 并调用其上的 create() 方法来获取更多的 T。更复杂的示例可能需要传递给 create 方法其他参数或重载。较不优雅的解决方法包括显式反射,传递 Class<T> 对象。例如,ArrayList.class.newInstance() 返回一个新构造的原始 ArrayList。您必须显式传递 Class 对象,并且基于反射的方法比普通构造函数或工厂对象要慢(尽管最近反射的速度有所提高)。您还依赖于该类公开无参构造函数,但并非总是如此。它可以实现,但从未被称为 "令人愉快" 的东西。(话虽如此,值得一提的是,在 Java 8 中,通过 Lambda 项目和相关技术,这种情况可能会有所改变。)

谢谢你的提示。看起来我必须这样做:/ - nux

6

5

很抱歉让你失望,但在Java中没有构造函数是不可能的。

Java在运行时会丢弃泛型信息(参见类型擦除)。


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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接