欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入IDEA Debug問題透析詳解

 更新時間:2023年01月08日 15:56:23   作者:郁乎文  
這篇文章主要為大家介紹了深入IDEA Debug問題透析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

本來通過問題引入,透析 IDEA Debug。通過閱讀本文可以學(xué)習(xí)如何通過 IDEA 的 Debug 功能解決實際問題。本文適合剛剛參加工作并且有使用 Spring 以及 JPA 經(jīng)驗的朋友。

問題引入

最近看了 eclipse 開源的集合 Eclipse Collections,覺得它的 api 相比 JDK 集合 api 簡潔,想在實際項目中使用,如下。

JDK api

 // users is List<String> 
 users.stream.map(user -> user.getName()).collect(Collectors.toList());

Eclipse Collections api

 //users is MutableList
 users.collect(user -> user.getName);

項目實際開發(fā)中使用集合最多的地方還是來自數(shù)據(jù)庫查詢,如下。

JDK api

List<User> findByCity(String city);

我想改成

MutableList<User> findByCity(String city);

然而報錯了

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.util.ArrayList<?>] to type [org.eclipse.collections.api.list.MutableList<?>] for value '[]'; nested exception is java.lang.IllegalArgumentException: Unsupported Collection interface: org.eclipse.collections.api.list.MutableList
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)

太長不看直接結(jié)論是改成下列代碼。

FastList<User> findByCity(String city);

Debug

對代碼簡單分析

報錯的地方都是 Spring 的包,證明我們使用的 Spring Data JPA 訪問數(shù)據(jù)庫,事實上也是。

查看類名稱,方法名稱。 有 convert.ConversionFailedException/convert.support.ConversionUtils.invokeConverter/convert.support.GenericConversionService.convert等等,關(guān)鍵詞 convert,我應(yīng)該聯(lián)想到這段代碼的功能是把什么類型 convert 到什么類型。

再分析報錯的那一行我們會更清晰一點。

  • result 是轉(zhuǎn)換的結(jié)果。
  • converter是轉(zhuǎn)換器,結(jié)合上面的結(jié)論,這個類肯定是真正執(zhí)行轉(zhuǎn)換的類,我們要的核心代碼肯定在這里,如果你直接去看的話,它肯定是一個接口,面向接口編程。
  • sourceType 源類型,結(jié)合上述分析肯定是原始類型。
  • targetType 目標(biāo)類型,同上不贅述。

打斷點

IDEA 可以直接點擊報錯 class 定位到源文件,這里我們先點擊 ConversionFailedException ,再點擊 ConversionUtils.java:47,發(fā)現(xiàn)都是報錯的異常,對我們沒有幫助。最后我們點擊 GenericConversionService.java:192,終于看到一行代碼了。

Object result = 
    ConversionUtils.invokeConverter(converter, source, sourceType, targetType);

斷點分析

執(zhí)行過程會停留在斷點處,我們可以查看上下文變量類的實例。這里我們以 converter 為例。按照數(shù)字步驟點擊,如下。

可能的 converter 如下:

1. java.lang.String -> java.lang.Enum
2. NO_OP
3. java.lang.Boolean -> java.lang.String
// 等等。。。。。

由于是底層方法,被調(diào)用的次數(shù)很多,在這個斷點停留的次數(shù)也很多。很多次不是我們想要的 converter

條件斷點

顧名思義 IDEA 會通過我們添加的條件來判斷這個斷點是否需要被處理。

我們想要的 converter 是什么呢?回到代碼分析階段,我們想要的 convertersourceTypetargetTypetargetType 類型是什么呢?回到我們自己寫的代碼。

MutableList<User> findByAdress(String address);

可以看到我們需要 targetTypeMutableList class。

下面添加條件斷點:

完整的條件如下:

MutableList.class.isAssignableFrom(targetType.getType());

添加成功的標(biāo)志如下。

單步調(diào)試

Debug 模式啟動程序,可以看到 IDEA 停留在我們的條件斷點上,并且targetType 的類型正是 MutableList。

單步調(diào)試代碼,來到 org.springframework.core.CollectionFactory#createCollection 方法。

部分代碼如下:

//省略的代碼
// 判斷集合類型是不是 ArrayList 或者 List,顯然這里不是
else if (ArrayList.class == collectionType || List.class == collectionType) {
  return new ArrayList<>(capacity);
}
//省略的代碼
else {
//如果是集合類型的接口 或者 不是集合類型拋出異常
  if (collectionType.isInterface() || !Collection.class.isAssignableFrom(collectionType)) {
    throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
  }
  try {
  //如果是集合類型的類,直接通過反射實例化。
    return (Collection<E>) ReflectionUtils.accessibleConstructor(collectionType).newInstance();
  }
}

重回代碼分析

我們的 targetType 的類型正是 MutableList,而 MutableList 是接口,走讀代碼可以發(fā)現(xiàn)最終會執(zhí)行下面的代碼,最終導(dǎo)致拋出異常。

if (collectionType.isInterface() || !Collection.class.isAssignableFrom(collectionType)) {
    throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
  }

翻看控制臺找到了下面的異常信息,這也側(cè)面反映我們之前找的報錯位置不是很精確。我們尋找異常時應(yīng)該選擇最原始的異常信息。

Caused by: java.lang.IllegalArgumentException: Unsupported Collection type: org.eclipse.collections.api.list.MutableList
	at org.springframework.core.CollectionFactory.createCollection(CollectionFactory.java:205)
	at org.springframework.core.convert.support.CollectionToCollectionConverter.convert(CollectionToCollectionConverter.java:81)

繼續(xù)分析源碼可以發(fā)現(xiàn),如果我們定義的類型不是接口,JPA 就會通過反射創(chuàng)建集合,即如下代碼:

return (Collection<E>) ReflectionUtils.accessibleConstructor(collectionType).newInstance();

所以我們只需要將 MutableList 換成它的實現(xiàn)類即可,比如 FastList。最終代碼如下:

FastList<User> findByCity(String city);

總結(jié)

本來通過解決實際問題介紹了 IDEA Debug 功能的使用。還有以下幾點需要注意。

  • 查找異常時要定位到最初始的異常,這樣往往能迅速處理問題。
  • 本文的問題只有在 sping boot 2.7.0 以下才會出現(xiàn),高版本已經(jīng)修復(fù)此問題。參見提交 spring data common
  • 使用非 Java 官方集合需要進行轉(zhuǎn)換,有微小的性能損耗,對于常規(guī)內(nèi)存操作來說影響很小。如果查詢數(shù)據(jù)上千上萬條時,應(yīng)該避免轉(zhuǎn)換。

源碼

以上就是深入IDEA Debug問題透析詳解的詳細內(nèi)容,更多關(guān)于IDEA Debug問題透析的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java多線程實現(xiàn)同時輸出

    Java多線程實現(xiàn)同時輸出

    這篇文章主要介紹了Java多線程實現(xiàn)同時打印的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • java根據(jù)圖片中綠色像素點的多少進行排序

    java根據(jù)圖片中綠色像素點的多少進行排序

    這篇文章主要介紹了java根據(jù)圖片中綠色像素點的多少進行排序,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 基于Java編寫一個粽子大作戰(zhàn)小游戲

    基于Java編寫一個粽子大作戰(zhàn)小游戲

    端午節(jié),又稱龍舟節(jié)、重午節(jié),是中國的傳統(tǒng)節(jié)日之一,每年農(nóng)歷五月初五慶祝,雖然端午假期已經(jīng)過去了,小編還是用Java編寫了一個粽子大作戰(zhàn)小游戲,感興趣的可以了解一下
    2023-06-06
  • Java實現(xiàn)FIFO任務(wù)調(diào)度隊列策略

    Java實現(xiàn)FIFO任務(wù)調(diào)度隊列策略

    在工作中,很多高并發(fā)的場景中,我們會用到隊列來實現(xiàn)大量的任務(wù)請求。當(dāng)任務(wù)需要某些特殊資源的時候,我們還需要合理的分配資源,讓隊列中的任務(wù)高效且有序完成任務(wù)。本文將為大家介紹通過java實現(xiàn)FIFO任務(wù)調(diào)度,需要的可以參考一下
    2021-12-12
  • Java基于PDFbox實現(xiàn)讀取處理PDF文件

    Java基于PDFbox實現(xiàn)讀取處理PDF文件

    PDFbox是一個開源的、基于Java的、支持PDF文檔生成的工具庫,它可以用于創(chuàng)建新的PDF文檔,修改現(xiàn)有的PDF文檔,還可以從PDF文檔中提取所需的內(nèi)容。本文將具體介紹一下PDFbox讀取處理PDF文件的示例代碼,感興趣的可以學(xué)習(xí)一下
    2022-02-02
  • java基于odbc連接oracle的實現(xiàn)方法

    java基于odbc連接oracle的實現(xiàn)方法

    這篇文章主要介紹了java基于odbc連接oracle的實現(xiàn)方法,結(jié)合實例形式分析了連接操作的具體步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2016-09-09
  • Java web自定義filter代碼實例

    Java web自定義filter代碼實例

    這篇文章主要介紹了Java web自定義filter代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12
  • Spring Boot實現(xiàn)郵件發(fā)送功能

    Spring Boot實現(xiàn)郵件發(fā)送功能

    這篇文章主要為大家詳細介紹了Spring Boot實現(xiàn)郵件發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • pom文件中${project.basedir}的使用

    pom文件中${project.basedir}的使用

    這篇文章主要介紹了pom文件中${project.basedir}的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java打成各種壓縮包的方法詳細匯總

    Java打成各種壓縮包的方法詳細匯總

    在工作過程中,需要將一個文件夾生成壓縮文件,然后提供給用戶下載,下面這篇文章主要給大家介紹了關(guān)于Java打成各種壓縮包的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-06-06

最新評論