2012-05-01 49 views
4

我通常是C#開發人員,新的Java和我試圖安裝使用泛型一些代碼。我的演示代碼如下所示:即使X應該與T匹配,也不能將X轉換爲T?

// Main.java 
public static void main(String[] args) { 
    MyBase my = getMeStuff(); 
    System.out.println(my.getSomething()); 
} 

private static <T extends MyBase> T getMeStuff(){ 
    return new MyDerived(123); 
} 

// MyBase/MyDerived.java 
public class MyBase { 
    private final int something; 

    protected MyBase(int something) { this.something = something; } 

    public int getSomething() { return something; } 
} 

public class MyDerived extends MyBase { 
    public MyDerived(int something) { super(something); } 
} 

這無法編譯:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Type mismatch: cannot convert from x.MyDerived to T 

at x.Main.getMeStuff(Main.java:14) 
at x.Main.main(Main.java:9) 

至於說,我通常是C#開發,使代碼看起來不錯乍一看。我可以通過改變getMeStuff向(T)添加一個轉換來「解決」這個錯誤,但是這種轉換真的有必要嗎?它聞起來有點像我忘記了什麼?

+4

如果你返回一個固定的已知類型爲什麼要使用一個通用的? –

+0

@Oli因爲實際的實現是更復雜的,並且可以返回許多類型中的一個(它實際上需要其通過反射實例化一類) –

回答

5

的問題是,返回類型可以是任何東西,從MyBase派生,你已經明確它鍵入的MyDerived,它甚至沒有在C#中工作,沒有一個演員。調用者可以指定SomeOtherDerived,它也來自MyBase,但與MyDerived無關。

public class MyBase{} 
public class MyDerived extends MyBase{} 
public class SomeOtherDerived extends MyBase{} 
public static <T extends MyBase> T getAnything(){ return (T)new MyDerived(); } 

public static void main(String[] args) { 
    SomeOtherDerived instance = getAnything(); //This is legal and bad 
} 

同樣重要的是要注意的是,即使有投,這是一個非常糟糕的事情,當與未明確提供的任何類型,稱爲很容易導致運行時異常。這也違背了泛型的概念,通過在非常具體的類型中確定應該是一種廣義的情況。

1

Java泛型希望能幫助您實現類型安全。

讓我用平行線:讓我們假設你寫了<T extends MyUIControl>,並且在一點上你用它MyButton s和別的地方MyPanel s--它不能被安全地轉換。

編譯器識別代碼這樣的情況。

相關問題