apache Commons Dbutils泛型方法及類型擦除問題詳解
使用Apache Commons Dbutils進行數據庫操作時,如何有效封裝泛型方法至關重要。本文將分析兩種不同的泛型方法實現,并解釋其中一種方法為何會引發“unchecked cast”警告。
問題源于使用QueryRunner進行數據庫查詢時,兩種泛型方法的差異:
方法一:直接接收class
public <T> T queryOne(Class<T> clazz, String sql, Object... params) throws SQLException { try { return queryRunner.query(connection, sql, new BeanHandler<>(clazz), params); } finally { // 省略代碼... } }
方法二:接收泛型類型T的對象作為參數:
public <T> T queryOne(T t, String sql, Object... params) throws SQLException { try { return queryRunner.query(connection, sql, new BeanHandler<T>((Class<? extends T>) t.getClass()), params); } finally { // 省略代碼... } }
方法二在 (Class extends T>) t.getClass() 處產生“unchecked cast”警告。這是由于Java的類型擦除機制:編譯后的字節碼不包含泛型信息。方法一中,Class
方法二的強制類型轉換 (Class extends T>) t.getClass() 存在類型安全風險。運行時,如果傳入的 t 對象實際類型并非 T 的子類,將拋出 ClassCastException。
為消除警告,可在方法二上添加 @SuppressWarnings(“unchecked”) 注解。但這僅壓制警告,無法消除潛在的運行時異常。方法一直接接收 Class