Java泛型,返回T的方法,其中<;T扩展字符串>;无法返回字符串

Java泛型,返回T的方法,其中<;T扩展字符串>;无法返回字符串,java,generics,java-8,Java,Generics,Java 8,我发现了以下代码: 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(

我发现了以下代码:

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)
       );
    }
}
公共类Ex7{
静态类转换器{
T2翻译(T1什么){
返回什么+“”;
}
}
公共静态void main(字符串[]args){
System.out.println(
新建转换器()。翻译(1)
);
}
}
我不明白为什么这段代码不能编译,因为T2是字符串,我想返回
方法“translate”中的字符串,编译器说它需要T2而不是字符串,但我知道T2是字符串,如下所述:

new Translator<Integer, String>().translate(1)
new Translator().translate(1)

有人能给我解释一下吗?

T2扩展字符串
是合法的,但毫无意义。没有扩展
字符串
,因为它是最后一个类。但是,编译器不会阻止你写这个,因为它不考虑边界类的“代码>最终< /代码>”。

将代码>字符串放在一旁,并考虑这些类:

class A {}
class B extends A {}
如果您声明这样的类:

static class Translator<T1, T2 extends A> {
    T2 translate(T1 what) {
       return new A();
    }
}
静态类转换器{
T2翻译(T1什么){
返回新的A();
}
}
希望你能明白为什么这是非法的:

Translator<String, B> t = new Translator<>();
B result = t.translate("");
Translator t=new Translator();
B结果=t.translate(“”);
这里,
result
应该是
B
的一个实例;但是该方法的实现意味着它将返回一个
A
。这是保证失败的,所以它是禁止的

<> >编译器不考虑<代码>字符串< /> >与<代码> a <代码>有关:可能存在子类,因此禁止您返回<>代码>字符串<代码>,其中可能会返回子类。

因为T2是字符串

这是最基本的部分。泛型类是可以使用各种类型的实例的模板。如果方法签名定义了
T2
,则即使它具有类似
扩展字符串的约束,它仍然是泛型的
T2
从来都不是
String
,它是某种未知类型,应该扩展
String


如果泛型类不考虑并返回<代码>字符串< /代码>,则违反返回<代码> T2< /代码>的方法定义。

<代码> T2扩展字符串是合法的,但荒谬:没有什么可以<代码>字符串< /代码>,因为它是最终的。此方法可以安全返回的唯一内容是
null
。因为您希望返回字符串,并且所提到的字符串是final T2在这里是不相关的,可能会从声明中删除,并且该方法应该是“硬编码”以返回字符串。问题是,如果我们让您的代码保持原样,只更改translate方法,使其返回新的B(),它也不会编译…@PrezesKozłowski correct。因为调用者可能期望它返回
A
的任何子类,可能是
C
,它是
A
的直接子类。除了literal
null
,您实际上无法从该方法返回任何内容。另请参见,这表明即使将
List
作为
translate
的返回值也是有效的,调用方可能会推断
X扩展字符串和列表
用于
T2
,而不会违反
T2扩展字符串
约束。当然,
translate
的实现不能满足这一期望,正如正确的所说,“除了literal
null
,您实际上不能从该方法返回任何内容”。唯一的选择是抛出异常或永不返回(即无休止地循环)。