请考虑以下代码:
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个电话的任何警告。
以下是我的问题,在第一个代码段中,T
中的哪一个用于转换返回值。
是来自参数的T
还是来自返回值的T
?为什么我没有明确指定退货类型(如&#34; 1方式&#34;)没有发出警告?
答案 0 :(得分:4)
通常使用参数类型,但如果定义了返回类型(如方式2),编译器也会检查它。
如果没有参数来获取T
的类型,则返回类型声明是必要的,然后称为类型推断。因此你甚至可以写:
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);
,你会得到编译时错误,因为编译器现在不知道使用了哪一个。
答案 1 :(得分:1)
在函数声明中定义'T'时,您还将定义它保存并返回的T类型。在你的情况下,你传递参数并期望相同的返回类型,并声明'T'作为扩展ExtType。因此,eclipse不会产生任何警告。