0

我们有以下代码:

class MyClass<T>{
    public void method(){
        List<T>= new ArrayList<T>();
    }
}

下面的理由正确吗?我们正在尝试从非静态方法实例化类型参数ArrayList<T>在哪里。的特定实例中的需求。对于实例化编译器必须明确知道类型。据我了解,编译器在已知的非静态上下文中标记类型参数,因此我们可以实例化。TmethodMyClass<T>MyClass<T>TTArrayList<T>

但是如果我们编写如下代码:

class MyClass<T>{
    public void method(){
        List<T>= new ArrayList<T>();
        new T();// Compile Error
    }
}

我们有一个编译错误。我知道我们可以应用抽象工厂模式或使用反射来满足这种需求。但是new运算符需要特定的类型。类型参数T在非静态上下文中是特定的。我在哪里推理错误?

4

2 回答 2

3

据我了解,编译器在已知的非静态上下文中标记类型参数 T,因此我们可以实例化 ArrayList。

不。即使在非静态上下文中,编译器也不知道类型T表示什么。起作用的原因new ArrayList<T>();是,编译器知道它ArrayList<E>有一个 0-arg 构造函数。类型参数T将被实际类型参数替换。它可以是任何类型。而且由于您可以创建任何ArrayList类型的,那很好。

但是 new 运算符需要特定的类型。类型参数 T 在非静态上下文中是特定的。我在哪里推理错误?

在 的情况下new T();,再次因为编译器不知道什么是类型T,因此它不知道是否有任何可访问的 0-arg 构造函数T。考虑一个类如下:

class Test {
    private int value;
    public Test(int value) { this.value = value; }
}

然后你将你的泛型类实例化为:

MyClass<Test> obj = new MyClass<Test>();

现在,假设编译器允许new T();,那么对于这个实例化,它就像在做 - new Test();。但在Test. 那么,您希望该代码在运行时表现如何?它肯定会抛出异常。这是编译器通过显示编译器错误来防止的。

T我们可以通过指定绑定 -向类型参数添加更多信息T extends Number。但这只会允许我们访问类型参数的方法。构造函数仍然无法访问。

于 2013-09-29T09:40:35.363 回答
2

编译器如何知道类 T(在运行时不存在)会有一个没有参数的构造函数?由于无法保证这一点,显然不应该允许!

于 2013-09-29T09:39:05.540 回答