2013-01-09 38 views
1

我試圖定義一個包裝android.view.View及其子類的類,並且包含一些渲染信息(人們可能將其稱爲View Model或PresentationModel)。Android編碼中的<T extends View>有沒有意義?

public class MyClass<T extends View> 
{ 
    private T view; 
    private Blah blah;  
} 

我的原始問題是,如果我應該使視圖變量的類型參數化或不。 Java的泛型實現似乎很簡單(例如,所有類型參數信息在編譯時都會被擦除),我可以在這裏找到兩個可能的優點。

1)向下看似冷卻器,即使我仍然需要在代碼中指定類型。

@SuppressWarnings("unchecked") 
public final <U extends View> U getView() 
{ 
    return (U) view; 
} 

通過以上,

Button btn = (Button) obj.getView(); 
((LinearLayout) obj).addView(view); 

變得

Button btn = obj.getView(); 
obj.<LinearLayout>addView(view); 

2)I可能能夠寫一些多晶型碼;

@Override 
public void bringToFront() 
{ 
    // stuff 
} 

如果一個方法被一些子類重新定義,

public final T getView() 
{ 
    return view; 
} 

以上,

obj.bringToFront(); 

強權的行爲不同,這取決於我們給類型參數。最大的問題是我不知道在Google的android框架中是否有任何實際的覆蓋情況。

目前,我會避免使用泛型,因爲顯然我不能使用HashMap與泛型類。

Map<String, MyClass<View>> objs = new HashMap<String, MyClass<View>>(); 
MtClass<Button> obj = objs.get(key); // type mismatch  
+1

你總是可以使用'MyClass <?在您的最後一個示例中將視圖>'作爲您的值的類型 – fge

+1

通常,在變量中使用變量在Java中被認爲是錯誤的代碼樣式,應該爲函數定義保留,請參閱Effective Java中的通配符一章。 –

回答

2

2)是不正確的,至少在你的例子。你提供的功能不是多態的,所以根據T不會有所不同。當然子類可以重新定義行爲,但這與T無關。

至於1),是的,它確實使代碼更漂亮,但它也使它非常不安全。考慮到你有類型的視圖T,你爲什麼要將它轉換爲U?根據你上面給出的代碼,這顯然是非法的,如果你沒有施放它,那將是一個編譯時錯誤,但現在只是一個運行時錯誤,除非類型匹配。即如果您有MyClass<Button>並且定義了T getView(),那麼代碼在沒有使用U或使用類型參數U的情況下工作,而MyClass<TextView>會在getView()上導致運行時錯誤,儘管它編譯正確。

至於你的最後一點,當你檢索從Map<K, V>一個對象,你只能證明對象是V,不是的V亞型,這就是爲什麼你的最後一個例子不能編譯。

總體而言,仿製藥是爲了增加代碼重用同時強制執行措施的類型安全,但是你提供的例子似乎只做了前者,並拋出類型安全窗外(這是公平的,是什麼一般的Android UI編程)。在你給出的例子中,似乎仿製藥對你的幫助不會超過對你的傷害。

+0

謝謝你們。至於2),我似乎有一個很大的誤解......;( – Quv

+0

)沒關係,泛型可能會非常混亂,而Java的實現更是如此 - 所以當試圖理解參數類型背後的理論時,祝你好運! –

相關問題