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(){}

};

感谢帮助。

4

4 回答 4

10

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

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

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

然后你的班级可以得到 aFactory<T>并要求create()它得到更多T的 s。例如,更复杂的示例可能需要create方法的附加参数或重载。

不太漂亮的解决方法包括显式反射、传递Class<T>对象。例如,ArrayList.class.newInstance()返回一个新构造的 raw ArrayList。您必须显式地传递Class对象,并且基于反射的方法比普通的构造函数或工厂对象要慢(尽管最近反射的速度一直在提高)。您还依赖于公开无参数构造函数的类,但情况并非总是如此。可以让它发挥作用,但这绝不是我所说的“令人愉快”。

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

于 2012-05-31T09:30:22.570 回答
6

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

于 2012-05-31T09:29:12.477 回答
5

很抱歉让您失望,但这在没有构造函数的 java 中是完全不可能的。

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

于 2012-05-31T09:30:02.307 回答
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;
    }
于 2012-05-31T09:34:27.137 回答