Java在通用方法中限制了参数

时间:2011-12-18 20:16:16

标签: java generics methods

我在泛型方法中测试了一些有界参数的东西,我发现了一些奇怪的行为 如果有人能够在下面的代码片段中解释这两个错误,那就太好了。

想象一下,有两个类Class1Class2都来自BaseClassClass2实现了一个接口。

Class1中,我有一个以下列方式返回Class2实例的方法:

public class Class2 extends BaseClass implements Interface {

    @Override
    public void method() {
        System.out.println("test"); //$NON-NLS-1$
    }
}

public class Class1 extends BaseClass {

    public <T extends BaseClass & Interface> T getTwo() {
        return new Class2();
        // Error: Type mismatch: cannot convert from Class2 to T
    }

    public static void main(String[] args) {
        Interface two = new Class1().getTwo();
        // Error: Bound mismatch: The generic method getTwo() of type Class1 is
        // not applicable for the arguments (). The inferred type Interface is
        // not a valid substitute for the bounded parameter <T extends BaseClass
        // & Interface>
        System.out.println(two);
    }
}

2 个答案:

答案 0 :(得分:5)

发生第一个编译错误,因为方法声明的类型参数由调用者指定,而不是方法实现。也就是说,给定

class Class3 extends BaseClass implements Interface { ... }

来电者可以写

Class3 c3 = new Class1().<Class3>getTwo();

,但方法实现返回Class2,这不是T = Class3的子类型。

发生第二个编译错误,因为调用程序未显式指定的类型参数是从方法参数和方法返回值赋给的变量的类型推断出来的。这种推断在这里失败了。 Java语言规范推荐的常用解决方法是在这种情况下明确指定类型参数(类型推断旨在为简单情况提供便利;它并不旨在涵盖所有情况)。

至于如何正确声明这个类型参数,我需要知道你试图用这些声明完成什么。

答案 1 :(得分:4)

为什么在方法getTwo中使用泛型,当知道它是Class2时?只需这样做:

public Class2 getTwo() {
    return new Class2();
}

如果您要覆盖方法public <T extends BaseClass & Interface> T getTwo(),编译器将允许您在impl的public Class2 getTwo()T Class2 >