最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入IDEA Debug問(wèn)題透析詳解

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

引言

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

問(wèn)題引入

最近看了 eclipse 開(kāi)源的集合 Eclipse Collections,覺(jué)得它的 api 相比 JDK 集合 api 簡(jiǎn)潔,想在實(shí)際項(xiàng)目中使用,如下。

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);

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

JDK api

List<User> findByCity(String city);

我想改成

MutableList<User> findByCity(String city);

然而報(bào)錯(cuò)了

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)

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

FastList<User> findByCity(String city);

Debug

對(duì)代碼簡(jiǎn)單分析

報(bào)錯(cuò)的地方都是 Spring 的包,證明我們使用的 Spring Data JPA 訪問(wèn)數(shù)據(jù)庫(kù),事實(shí)上也是。

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

再分析報(bào)錯(cuò)的那一行我們會(huì)更清晰一點(diǎn)。

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

打斷點(diǎn)

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

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

斷點(diǎn)分析

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

可能的 converter 如下:

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

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

條件斷點(diǎn)

顧名思義 IDEA 會(huì)通過(guò)我們添加的條件來(lái)判斷這個(gè)斷點(diǎn)是否需要被處理。

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

MutableList<User> findByAdress(String address);

可以看到我們需要 targetTypeMutableList class。

下面添加條件斷點(diǎn):

完整的條件如下:

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

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

單步調(diào)試

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

單步調(diào)試代碼,來(lái)到 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 {
  //如果是集合類型的類,直接通過(guò)反射實(shí)例化。
    return (Collection<E>) ReflectionUtils.accessibleConstructor(collectionType).newInstance();
  }
}

重回代碼分析

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

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

翻看控制臺(tái)找到了下面的異常信息,這也側(cè)面反映我們之前找的報(bào)錯(cuò)位置不是很精確。我們尋找異常時(shí)應(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 就會(huì)通過(guò)反射創(chuàng)建集合,即如下代碼:

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

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

FastList<User> findByCity(String city);

總結(jié)

本來(lái)通過(guò)解決實(shí)際問(wèn)題介紹了 IDEA Debug 功能的使用。還有以下幾點(diǎn)需要注意。

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

源碼

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

相關(guān)文章

  • springBoot中的properties配置解析

    springBoot中的properties配置解析

    這篇文章主要介紹了springBoot中的properties配置解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 淺談JAVA并發(fā)之ReentrantLock

    淺談JAVA并發(fā)之ReentrantLock

    本文主要介紹了基于AQS實(shí)現(xiàn)的ReentrantLock(重入鎖),感興趣的同學(xué),可以參考下。
    2021-06-06
  • Java中常見(jiàn)的4種限流算法詳解

    Java中常見(jiàn)的4種限流算法詳解

    這篇文章主要介紹了Java中常見(jiàn)的4種限流算法詳解,FixedWindowRateLimiter 類表示一個(gè)固定窗口限流器,使用 limit 和 interval 參數(shù)分別表示限制請(qǐng)求數(shù)量和時(shí)間間隔,缺點(diǎn)是短時(shí)間內(nèi)可能會(huì)流量翻倍,需要的朋友可以參考下
    2023-12-12
  • Redisson分布式鎖的原理和代碼實(shí)例

    Redisson分布式鎖的原理和代碼實(shí)例

    這篇文章主要介紹了Redisson分布式鎖的原理和代碼實(shí)例,在分布式系統(tǒng)中,鎖機(jī)制是非常重要的,Redisson是一個(gè)基于Redis的Java應(yīng)用程序,常常被應(yīng)用作為分布式鎖的解決方案,需要的朋友可以參考下
    2024-01-01
  • SpringBoot實(shí)現(xiàn)多端口監(jiān)聽(tīng)的代碼示例

    SpringBoot實(shí)現(xiàn)多端口監(jiān)聽(tīng)的代碼示例

    當(dāng)你需要在同一個(gè)Spring Boot應(yīng)用中,通過(guò)不同的端口來(lái)提供不同的服務(wù)或功能時(shí),就需要實(shí)現(xiàn)多端口監(jiān)聽(tīng),所以本文給大家介紹了SpringBoot實(shí)現(xiàn)多端口監(jiān)聽(tīng)的方法示例,并有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-09-09
  • Java魔法值處理的四種方式

    Java魔法值處理的四種方式

    這篇文章主要介紹了Java魔法值處理的四種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java堆&優(yōu)先級(jí)隊(duì)列示例講解(上)

    Java堆&優(yōu)先級(jí)隊(duì)列示例講解(上)

    這篇文章主要通過(guò)示例詳細(xì)為大家介紹Java中的堆以及優(yōu)先級(jí)隊(duì)列,文中的示例代碼講解詳細(xì),對(duì)我們了解java有一定幫助,需要的可以參考一下
    2022-03-03
  • JAVA開(kāi)發(fā)環(huán)境搭建教程

    JAVA開(kāi)發(fā)環(huán)境搭建教程

    這篇文章主要為大家詳細(xì)介紹了JAVA開(kāi)發(fā)環(huán)境搭建教程,配置JAVA開(kāi)發(fā)環(huán)境,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 淺談Java中的this作為返回值時(shí)返回的是什么

    淺談Java中的this作為返回值時(shí)返回的是什么

    Java中的this作為返回值時(shí)返回的是什么?下面小編就為大家介紹一下Java中的this作為返回值時(shí)返回。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • java中maven下載和安裝步驟說(shuō)明

    java中maven下載和安裝步驟說(shuō)明

    在本篇文章里小編給大家分享的是一篇關(guān)于java中maven下載和安裝步驟說(shuō)明內(nèi)容,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-02-02

最新評(píng)論

保靖县| 伊通| 阜南县| 平陆县| 嘉义县| 枝江市| 莱西市| 新龙县| 宿松县| 凉山| 翼城县| 抚顺市| 临泽县| 博白县| 青河县| 平塘县| 佛学| 乾安县| 伊金霍洛旗| 林州市| 新营市| 崇文区| 福泉市| 瑞丽市| 额尔古纳市| 鄂温| 平利县| 巴林右旗| 鄢陵县| 尉犁县| 盐亭县| 明光市| 合肥市| 马龙县| 秦安县| 靖宇县| 恭城| 社旗县| 淅川县| 松阳县| 会泽县|