我发现以下代码:
public class Ex7 {
static class Translator<T1, T2 extends String> {
T2 translate(T1 what) {
return what + " ";
}
}
public static void main(String[] args) {
System.out.println(
new Translator<Integer, String>().translate(1)
);
}
}
我不明白为什么这段代码不能编译,因为T2是String,我想返回
来自方法“ translate”的字符串,编译器表示它期望使用T2而不是String,但是我知道T2是字符串,如下所示:
new Translator<Integer, String>().translate(1)
有人可以向我解释一下吗?
答案 0 :(得分:1)
T2 extends String
是合法的,但却是荒谬的。 String
没有什么扩展,因为它是最后一堂课。但是,编译器不会阻止您编写此代码,因为它没有考虑边界类的final
-ness。
将String
放在一边,并考虑以下类:
class A {}
class B extends A {}
如果您声明这样的类:
static class Translator<T1, T2 extends A> {
T2 translate(T1 what) {
return new A();
}
}
您可以希望看到为什么这是非法的:
Translator<String, B> t = new Translator<>();
B result = t.translate("");
在这里,result
应该是B
的实例;但是该方法的实现意味着它正在返回A
。保证会失败,因此被禁止。
在这方面,编译器认为String
与A
没有什么不同:可能是子类,因此它禁止您返回{{1} }可能会返回子类 。
答案 1 :(得分:0)
因为T2是字符串
这是必不可少的部分。泛型类是可以使用各种类型的实例的模板。如果方法签名定义了T2
,即使它具有类似extends String
的约束,它也将保持通用。 T2
从不String
,它是应该扩展String
的某种未知类型。
如果泛型类不考虑并返回String
,则它违反了返回T2
的方法定义。