2

考虑以下代码:

class ExtType extends MyType{};

class MyClass {
    MyType myField;

    public <T extends MyType> T foo(Class<T> clazz) {
        return (T)myField;
    }
}

现在我想调用foo方法,我可以通过两种方式做到这一点:

1种方式:

(new MyClass()).foo(ExtType.class);

2种方法:

(new MyClass()).<ExtType>foo(ExtType.class);

有趣的是,即使该方法被声明为参数化,Eclipse 也不会在 1 次调用时发出任何警告。

这是我的问题,在第一个代码片段中,哪个Ts 用于转换返回值。它是T来自参数还是T来自返回值?为什么如果我没有明确指定返回类型(如“1 方式”)不发出警告?

4

2 回答 2

4

通常使用参数类型,但如果定义了返回类型(如方式 2),编译器也会检查它。

如果没有参数来获取Tfrom 的类型,则返回类型声明将是必要的,这称为类型推断。因此你甚至可以写:

public <T extends MyType> T foo() {
    return (T)myField;
}


ExtType t = (new MyClass()).foo();

在某些情况下,您需要帮助编译器并指定要使用的类型,从而获得类似(new MyClass()).<ExtType>foo(ExtType.class);. 但是请注意,如果您定义不同的类型,例如(new MyClass()).<MyType>foo(ExtType.class);,您会得到一个编译时错误,因为编译器现在不知道使用的是哪一个。

于 2012-04-10T08:26:59.040 回答
1

当您在函数声明中定义“T”时,您还将定义它持有和返回的 T 类型。在您的情况下,您正在传递参数并期望相同的返回类型并将“T”声明为扩展 ExtType。因此,eclipse 不会产生任何警告。

于 2012-04-10T08:27:52.193 回答