2016-08-18 26 views
3

您好我在使用java中的泛型類型時遇到了問題。實際的問題是,當我在方法聲明上使用泛型時工作正常。然後,如果我添加一個泛型類型的接口聲明代碼不會編譯。以下是工作代碼:爲什麼JAVA無法在接口中使用泛型時編譯

public interface IRuntimeConvert { 
    public <T> T convertInstanceOfObject(String o, Class<T> clazz); 
} 

public class RuntimeConvertImpl implements IRuntimeConvert { 

    private final Map<String, Object> hashMap; 

    public RuntimeConvertImpl(Map<String, Object> hashMap) { 
     this.hashMap = hashMap; 
    } 

    @Override 
    public <T> T convertInstanceOfObject(String o, Class<T> clazz) { 
     try { 
      return clazz.cast(hashMap.get(o)); 
     } catch (ClassCastException e) { 
      return null; 
     } 
    } 
} 

public static void main(String[] args) { 

    Map<String, Object> hashMap = new HashMap<>(); 
    hashMap.put("s", "string"); 
    hashMap.put("i", 0); 
    hashMap.put("l", 0L); 

    IRuntimeConvert rtConvert = new RuntimeConvertImpl(hashMap); 

    String s = rtConvert.convertInstanceOfObject("s", String.class); 
    System.out.println(s); 
    Integer i = rtConvert.convertInstanceOfObject("i", Integer.class); 
    System.out.println(i); 
    Long l = rtConvert.convertInstanceOfObject("l", Long.class); 
    System.out.println(l); 
} 

上面的代碼正在編譯。當我做出以下更改時,代碼不可編譯。

public interface IRuntimeConvert<S> { 

    public <T> T convertInstanceOfObject(String o, Class<T> clazz); 

    public S getSomething(S s); 
} 

public class RuntimeConvertImpl implements IRuntimeConvert<Object> { 

    private final Map<String, Object> hashMap; 

    public RuntimeConvertImpl(Map<String, Object> hashMap) { 
     this.hashMap = hashMap; 
    } 

    @Override 
    public <T> T convertInstanceOfObject(String o, Class<T> clazz) { 
     try { 
      return clazz.cast(hashMap.get(o)); 
     } catch (ClassCastException e) { 
      return null; 
     } 
    } 

    @Override 
    public Object getSomething(Object s) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

} 

在主類上述變化之後予encouted投誤差的方法rtConvert.convertInstanceOfObject(「S」,String.class)的每個調用錯誤消息的類型:

Incompatible types: Object cannot be converted to String. 

如果我嘗試運行主體,我會得到:線程「main」中的異常java.lang.RuntimeException:不可編譯的源代碼 - 不兼容的類型:java.lang.Object不能轉換爲java.lang.String

+0

類型刪除。 Java泛型不像C++模板:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html – duffymo

+3

您好cparaskeva - 你可以編輯你的問題,包括更多的細節如何以及它不編譯? –

+5

如果出現錯誤,請始終包含錯誤消息。 – Thilo

回答

1

它可能是Java試圖引用泛型類型的一個問題。如果您在主要方法中指定rtConvert變量的泛型類型,則可以解決此問題:IRuntimeConvert<Object> rtConvert,而不僅僅是IRuntimeConvert rtConvert

默認情況下,我總是嘗試指定泛型變量類型。

+0

是的,謝謝你,這是問題!不過,我認爲,默認情況下,Java正在將未綁定類型替換爲對象 – cparaskeva

3

這是因爲您已在執行中指定的通用類型爲Object與以下行:

public class RuntimeConvertImpl implements IRuntimeConvert<Object> { 

因此,爲了getSomething通話將總是要返回一個Object。然而,由於StringObject一個子類,這不能被自動轉換爲String,你必須做一些事情,如:

String s = (String) rtConvert.getSomething(); 

請注意,這並不能保證類型安全,並可能導致ClassCastException小號。

+0

如果您想使用泛型...請使用它們!如果你想要返回一個字符串對象只是instanciate它:IRuntimeConvert rtConvert 但是,作爲這個答案解釋的問題,我投它 – loicmathieu

+0

謝謝tou for you解釋!事實上,我對仿製藥產生了懷疑。 – cparaskeva

+0

據我所知,在main()方法中沒有'getSomething()'。因此在這裏沒有編譯錯誤。 –

2

我無法爲您編寫Java語言規範。我只是得出一些結論。

如果更改main()一行:

IRuntimeConvert<?> rtConvert = new RuntimeConvertImpl(hashMap); 
//  type ^^^^ 

然後main()將編譯。因此,顯然javac需要全部要爲實際對象類型定義的泛型。然後它可以處理方法級通用參數。

+0

我已經給出了這個答案。 –

+0

這發生在並行編輯。反正也是+1。 –

相關問題