泛型类和非静态方法

时间:2013-09-29 09:36:27

标签: java generics instance type-parameter

我们有以下代码:

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

以下原因是否正确?我们试图从非静态方法实现ArrayList<T> T,其中method是类型参数。 MyClass<T>的特定实例中需要MyClass<T>。对于instanciate T编译器必须明确知道类型T。据我所知,编译器在非静态上下文中标记类型参数ArrayList<T>已知,因此我们可以实现class MyClass<T>{ public void method(){ List<T>= new ArrayList<T>(); new T();// Compile Error } }

但是如果我们写下面的代码:

new

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

2 个答案:

答案 0 :(得分:3)

  

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

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

  

但新操作员需要特定类型。类型parametr T是特定的非静态上下文。我的错误推理在哪里?

对于new T();,由于编译器不知道T是什么类型,因此它不知道是否存在{{1}的任何可访问的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();中没有0-arg构造函数。那么,您希望代码在运行时如何运行?它肯定会抛出异常。这是编译器通过显示编译器错误来阻止的。

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

答案 1 :(得分:2)

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