簡體   English   中英

java泛型方法警告“未經檢查的強制轉換”

[英]java generic method warning “Unchecked cast”

我寫了一個替換View.findViewById(int id) ,但是我得到了一個警告: 在此輸入圖像描述

這個方法有什么問題嗎? 或者如何避免它?

我相信這就是警告的原因:Java允許向下轉換,即將類型X的對象轉換為X的子類。但是,這需要在運行時進行檢查。 例如:

Object x1 = <... something that returns an object that may be a String ...>;
String x2 = (String)x1;

演員將嘗試將x1視為String 但是x1可以是任何Object 它可能是也可能不是String 只有當x1實際上是一個String ; 否則你在運行時得到一個ClassCastException

代碼中的問題是TView的子類,這意味着強制轉換通常會導致在運行時執行相同類型的檢查。 但是,由於類型擦除,程序在代碼中此時實際上並沒有關於T類的信息,這意味着它無法執行檢查。 因此,您將使用未經檢查的操作收到有關該程序的警告。 程序無法保證,當此方法返回時,返回的對象實際上將是T類的實例。

我嘗試了一些測試用例,發現檢查通常發生在調用泛型方法的語句中。 假設View2擴展了View ,並且您希望以返回View2的方式使用find 然后:

View2 v = YourClass.<View2>find(x, id);

如果findViewById找到的對象實際上不是View2 ,那么你將得到一個ClassCastException 但:

View v = YourClass.<View2>find(x, id);

假設findViewById返回其他一些視圖。 基於我的測試,即使type參數是View2 ,也不會拋出異常; 因為這被分配到一個View ,如果結果是其他視圖,它將正常工作,不會檢查View2

String s = YourClass.<View2>find(x, id).toString();

假設findViewById返回其他一些視圖。 當我嘗試這個時,我認為它不會拋出異常,因為另一個視圖也會有toString() (就像所有的Object一樣)。 但這確實拋出了ClassCastException

我不知道是否有一個很好的方法來解決它。 一種可能性是添加第三個參數來find以表示T的類,並使用其cast方法:

public static <T extends View> T find(View view, int id, Class<T> theClass) {
    return theClass.cast(view.findViewById(id));
}

View v = YourClass.find(x, id, View2.class);

這有效 - 如果findViewById返回錯誤的類,它會從cast()方法拋出異常。 但是,為每次使用添加第三個參數可能不太吸引人,即使它可能允許您從調用中消除顯式泛型類型參數。

我認為這是一個可以忽略警告的情況,並使用@SuppressWarnings("unchecked")來停止警告顯示,如果你可能有時程序可能會繼續而不是拋出異常當findViewById返回錯誤的視圖時。

免責聲明:我的測試是使用Java 8進行的。我沒有使用任何在Java 7中無效的東西。但是如果Android仍然沒有完全實現Java 7,我寫的一些內容可能是錯誤的。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM