2010-06-28 36 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