2010-06-01 74 views
1

我有如下的類。支持返回不同類型的方法的設計類/接口

public interface ITest <T> 
{ 
    public Set<T> methodHere(); 
} 

public class test1 implements ITest<String> 
{ 
    Set<String> methodHere(){ 
     return // Set of String 
    } 
} 

public class test2 implements ITest<Integer> 
{ 
    Set<Integer> methodHere(){ 
    return // Set of Integer 
    } 
} 

public class ITestFactory { 
public static ITest getInstance(int type) { 
    if(type == 1) return new test1(); 
    else if(type == 2) return new test2(); 
} 
} 
public class TestUser { 
    public doSomething(int type) { 
     ITest t = ITestFactory.getInstance(type); 
     if(type == 1) Set<Integer> i = t.methodHere(); 
     else if(type == 2) Set<String> s = t.methodHere(); 
     ... 
    } 
} 

工廠類有一個警告,ITest被用作原始類型。我應該做些什麼修改才能擺脫它?

TestUser代碼看起來很醜。我錯過了非常基本的東西嗎?我不想用Set<?>

感謝 Nayn

回答

3

您可以返回ITest<?>擺脫的警告,但可能你想有一個更強烈鍵入的形式給出:

public class TestFactory { 
    public static ITest<?> getInstance(int type) { 
     if(type == 1) 
     return new test1(); 
     else if(type == 2) 
     return new test2(); 
     else 
     throw new IllegalArgumentException("Unknown type"); 
    } 

    public static <T> ITest<T> getInstance(Class<T> clazz) { 
     if(clazz == String.class) 
     return new test1(); 
     else if(clazz == Integer.class) 
     return new test2(); 
     else 
     throw new IllegalArgumentException("Unknown type"); 
    } 
} 
+0

雖然這是一個很好的答案,但@Thirler的評論「當您調用getInstance時,不可能知道哪種類型將返回」,這讓我重新思考我的設計。我不使用泛型,但創建了一個乾淨的類層次結構。 – Nayn 2010-06-01 13:07:23

+0

更新了我的問題。我仍然不正確。 – Nayn 2010-06-02 00:07:25

0

在你的情況沒有對泛型參數實際上是任何特定用途的有意義的更換,但是你可以添加或者<Object><?>到方法簽名以擺脫警告。

我看到的示例代碼中的一個更大的問題是,在命名類和方法時,您沒有遵循JCC

+0

感謝。我在我的實際代碼中遵循了正確的JCC。 – Nayn 2010-06-01 11:08:26

0

當您調用getInstance時,不可能知道將返回哪種類型。

但是,您可以更改工廠方法的簽名使用泛型:

public <A> ITest<A> getInstance(Class<A> type) 
{ 

} 
+0

這不會直接幫助,因爲他使用'int'來指定類型。他當然可以用一些'instanceof'檢查替換int。 – Esko 2010-06-01 11:04:47

+0

很顯然,實施需要改變。但真正的變化是調用方法需要知道將要返回的類型。 – Thirler 2010-06-01 11:10:37

+0

是的。我想我們都是對的? :) – Esko 2010-06-01 11:20:11

0

沒有機會 - 除了從supressing警告本身。在Java中,通常不可能聲明只有不同返回類型的方法。使用泛型沒有「逃避」。具有相同名稱且返回不同類型的方法需要不同的參數簽名(請參閱:重載)。

如果你看看相應的字節碼,你會發現MethodHere會返回一個Object。這稱爲類型擦除。通用參數僅供編譯器用於檢查/確保類型安全性。

一如既往 - 返回一個公共的超類型,並讓方法調用者確定對象類型(如在適配器模式中使用)。

相關問題