近距離接觸java 泛型

  • 簡述
    大家都知道java的泛型是在編譯期生效,在運行時會被擦除。這個概念在學習了java泛型後,就只是硬生生的背下來了。而平時使用泛型時,也只是採用最簡單的用法——在使用集合時,做一下類型檢查。稍微深入一點,也就將反射與泛型結合使用,如此而已。而小編今天碰到一個與泛型有關的問題,一個神奇的bug。
  • 問題描述
    小編的項目使用java 的SSM框架搭建。在其中一個接口編寫中,service接口類以及實現類都使用了List<Bean> 這樣的接口。然而在mybatis的xml中自定義了一個查詢,返回類型爲map。而問題在於map的字段和實際的對象屬性並不是一致的。然後錯誤的代碼卻跑出了正確的結果。

service接口層代碼:

List<CashFlow> selectCashFlowAndDetail(@Param("proId")Long proId, @Param("itemType")Integer itemType, @Param("condition")String condition);

service 實現類代碼:

@Override
    public Message getCashFlows(Long proId, Integer itemType) {
        // 拼接行列轉換sql
        String conditon = monthService.proMonthCondition(proId, "rate");
        try{
            List<CashFlow> result = cashFlowMapper.selectCashFlowAndDetail(proId, itemType, conditon);
            Message message = Message.successMessage(result);
            return message;
        } catch (Exception e) {
            logger.error("獲取現金流列表失敗!", e);
            return Message.errorMessage(500, "獲取現金流列表失敗!");
        }
    }

mybatis 自定義sql:

 <!--獲取現金流明細-->
  <select id="selectCashFlowAndDetail" resultType="map">
 .......
  </select>

Cashflow定義:

public class CashFlow extends BaseEntity{
    private Long id;

    private Long proId;
    // 條目名稱
    private String itemName;

    private String itemContent;

    // 項目類型: 1:進項, 2: 出項
    private Integer itemType;

    // 總金額
    private BigDecimal amount;

    @JsonFormat(timezone = "GMT+8", pattern = "YYYY-MM-dd HH:mm:ss")
    private Date createTime;

    @JsonFormat(timezone = "GMT+8", pattern = "YYYY-MM-dd HH:mm:ss")
    private Date updateTime;

    private String remark;
}

返回結果:
結果

  • 分析
    由於mysql返回了明細的數據,所以數據字段是遠遠多於聲明的實體類的。而返回的結果卻是用的List<Cashflow>接收的。也就是說,用一個簡潔的類但是接收了大量原本未聲明的數據。這段代碼本來是存在問題的,我們聲明的接收對象與實際的結果對象並不匹配。但是卻通過了java的編譯,並正確的得到了結果。
    其主要原因便是泛型。由於我們的接口層和實現類保持了相同的接口,所以編譯器並沒有發現問題。但是在運行時,泛型已經被擦除了,所以List<Map> 和List<Cashflow>都是一樣的集合List。所以實際運行時,也不會有問題。所以我們用List<Cashflow> 拿到了List<Map>的數據。而代碼中並沒有操作集合中的元素,就直接以json的形式返回前臺了,前臺也正確展示了結果。而此時如果我們對集合中的元素進行操作,那麼自動的類型轉化就會出現問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章