2014-11-17 29 views
1
SqlOutParameter out = new SqlOutParameter("out_refcursor",OracleTypes.CURSOR,new StudentRowMapper()); 

//一些代碼..類型安全:未選中從Object強制列出

MapSqlParameterSource parameters = createMapSqlParameterSource(); 
parameters.addValue("in_studentid","101"); 

Map<String, Object> result = simpleJdbcCall.execute(parameters); 
List<Student> students = (List<Student>) result.get("out_refcursor"); // here I get a warning 

定義​​方法:

Map<String, Object> org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SqlParameterSource parameterSource) 

「執行存儲過程並返回地圖輸出參數,如參數聲明中的名稱所示。「

上述行上的警告:List<Student> students = (List<Student>) result.get("out_refcursor");

是「類型安全:未選中從Object強制轉換成List」

我明白這只是一個編譯時警告,並Offcourse我可以做一個@SuppressWarnings("unchecked")來說,攔截它。

問題:但我該如何正確施放它?我嘗試了

  1. 一種方法是

    List<Student> students = castObject(result.get("out_refcursor"));

    @SuppressWarnings("unchecked") 
        private static <T extends List<?>> T castObject(Object obj){ 
         return (T)obj; 
        } 
    

不過我不得不把@SuppressWarnings("unchecked")在castObject()方法。我不知道這是否是正確的做法。

  • 方式二我試圖,

    List<?> students = castObject(result.get("out_refcursor"));

    Student student = (Student)students.get(0); 
    
    private static <T extends List<?>> List<?> castObject(Object obj){ 
         if(obj instanceof List<?>) { 
          return (List<Student>)obj; 
         } 
         return null; 
    } 
    
  • 任何建議/意見是受歡迎的。

    +0

    如果您知道返回的值是'名單',你的罰款。 –

    +1

    第一種方法是罰款,如果你知道它將永遠返回列表如果你不確定它會返回什麼,你應該使用你的第三種方法... – brso05

    +0

    我知道它總是會返回列表',所以它很乾淨編碼把@SupressWarnings(「unchecked」)在那種情況下?第三種方法也會避免警告,但我覺得代碼太多 – spiderman

    回答

    4

    你的第二個解決方案將不會幫助(由於Type Erasure),並且會導致其他問題,所以可能不是一個好主意。

    第一種方法可能會在實際中使用,但確實有點狡猾。有子類的泛型類型繼承其參數在Java之間的微妙(但巨大)的差異 - 即ArrayList<Integer>不是ArrayList<Object>一個子類,但ArrayList<String>是子類型的Collection<String>:看a more fun example。更正式的計算機科學背景Wikipedia entry on Covariance

    因此,國際海事組織應該保留鑄件,保留(必要)註釋,並抓住ClassCastException以確保涵蓋例外(因此名稱)的情況。

    +0

    謝謝你所有的參考。但是,我怎樣才能把它保留爲'List ',因爲result.get(「out_refcursor」)'返回一個'Object'不是一個對象列表 – spiderman

    +0

    哦,對,誤解了,對不起。我認爲你也可以立即將它轉換爲'List ',並直接在註解中保留註釋(也許有評論爲什麼它是安全的),因爲其他方法不會更安全或刪除警告。如果你想,你總是可以趕上'ClassCastException'並處理_that_實際的錯誤情況... – declension

    +0

    好吧,看起來像這是推薦的方法,謝謝+ 1 – spiderman

    3

    只要您知道List的元素的類名,就可以使用類似的方法。這裏有一個問題,硬編碼的實例。

    public static <T> List<T> castList(Object obj, Class<T> clazz) 
    { 
        List<T> result = new ArrayList<T>(); 
        if(obj instanceof List<?>) 
        { 
         for (Object o : (List<?>) obj) 
         { 
          result.add(clazz.cast(o)); 
         } 
         return result; 
        } 
        return null; 
    } 
    

    用法:

    List<Student> students = castList(result.get("out_refcursor"), Student.class); 
    
    +0

    對於我的理解,該泛型'castList()'爲+1 – spiderman