Java:在方法返回中使用泛型,它与泛型类参数不同

Ily*_*ich 4 java generics


    class SomeClass<E> {
       Map<String, String> someMethod();
    }

和用法


    SomeClass a = new SomeClass();
    a.someMethod().get("foo") // returns object, not string!

    //This code would not even compile
    String s = a.someMethod().get("foo");

但是,如果我从SomeClass中删除泛化(<E>) - 它可以工作.

如果我将此方法提取到接口并在声明中使用接口,它也可以工作:


    interface Foo {
     Map<String, String> someMethod();
    }

    class SomeClass implements Foo {
    //.....
    }

    Foo foo = new SomeClass();

    String s = foo.someMethod().getString("A");//it works

为什么会这样?我在哪里可以阅读它?什么是最好的解决方案?谢谢.

Jon*_*eet 10

解决方案不是使SomeClass非泛型 - 避免使用原始类型.例如,这工作正常:

import java.util.*;

class SomeClass<E> {
   Map<String, String> someMethod() {
      return null;
   }
}

public class Test {
    public static void main(String[] args) {
        SomeClass<Integer> a = new SomeClass<Integer>();
        String value = a.someMethod().get("foo");
    }
}
Run Code Online (Sandbox Code Playgroud)

不可否认,如果您使用原始类型,该方法有效地应用了类型擦除,这有点奇怪 - 但您基本上应该避免这样做.

我目前无法找到有关JLS中原始类型行为的任何解释,但第4.8节确实包含此警告:

原始类型的使用仅允许作为遗留代码兼容性的让步.强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型.未来版本的Java编程语言可能会禁止使用原始类型.