2010-06-28 45 views
4
 

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

和使用的Java:使用仿制药,从通用类参数

 

    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的删除泛化(<Ë>)方法返回 - 它的工作原理。

如果我提取这种方法界面和使用界面在声明它也适用:

 

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

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

    Foo foo = new SomeClass(); 

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

为什么会发生?我在哪里可以读到它?什么是最好的解决方法? 谢谢。

回答

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"); 
    } 
} 

诚然这是有点奇怪,该方法有效地具有类型擦除,如果你使用原始型应用 - 但你应该基本上避免这样做下手。

我目前无法找到在JLS原始类型的行为的任何解释,但section 4.8确实有这样的警告:

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

+1

'SomeClass a = new SomeClass();'也可以。 – 2010-06-28 12:45:35

+0

在第4.8章结尾附近,有一个讨论使用NonGeneric类和RawMember类来显示它,它至少对静态成员('RawMember类'中的'Collection ')至少有效......真奇怪。 – 2010-06-28 12:51:40

+0

@Andreas_D:我看到了,但我不确定它的情况是否完全相同。这确实很奇怪。 – 2010-06-28 13:00:51