使用泛型方法的Java类型擦除

使用泛型方法的Java类型擦除,java,generics,type-erasure,Java,Generics,Type Erasure,为什么类型推断在这种特殊情况下不起作用 public class ClassB<O> { public <T> T echo(T msg) { return msg; } public void doSomething(O a) { } public static void main() { // Test 1 ClassB<Object> sampleB = new ClassB<>(); // No com

为什么类型推断在这种特殊情况下不起作用

public class ClassB<O> {

public <T> T echo(T msg) {
    return msg;
}

public void doSomething(O a) {
}

public static void main() {
    // Test 1
    ClassB<Object> sampleB = new ClassB<>();
    // No compile time type error.
    // <T> and <O> are different.
    String test = sampleB.echo("");

    // Test 2
    ClassB sampleB1 = new ClassB();
    // Causes compile time type error.
    String test2 = sampleB1.echo("");
}
}
而不是

String test2 = (String) sampleB1.echo("");

泛型是选择性加入的,因为它们是在Java5中添加的,旧代码仍然需要工作

ClassB sampleB1 = new ClassB();  // this is a raw type
当您通过使用原始类型选择退出时,您将无法获得任何功能,包括泛型类型推断,您对方法的推断将被忽略。您将得到一个编译器警告,告诉您最好不要使用原始类型

方法返回类型与此有什么关系


没什么。你在方法上声明了,它只对该方法可见,它与类上的O完全无关,除非你做了类似的事情,它甚至可以隐藏你可以调用它的其他东西,甚至-但不要这样做。

如果将ClassB视为ClassB,为什么旧代码不起作用?@Chirayuchirpal这是一个好问题。他们这样做是为了让旧代码继续工作,但它却破坏了旧代码,因为我试图在不更改任何其他内容的情况下添加到现有类中,但旧代码现在被破坏了,因为我不再获取类型根据我的旧代码推断。它不是这样工作的:-如果你不接触源文件,它仍然会编译。如果你更新它,你必须一路更新它,至少一个变量。请注意,这些都是编译时错误,我们会立即通知您,但不会在运行时发现。与其他一些语言不同,这是一条非常平滑的升级路径
ClassB sampleB1 = new ClassB();  // this is a raw type