1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        IntelliJ IDEA 老司機(jī),還沒用過這 5 個(gè) Intellij IDEA 調(diào)試魔法?

        共 1617字,需瀏覽 4分鐘

         ·

        2022-02-22 08:48


        來自:日拱一兵

        前言

        今天給大家?guī)?5 個(gè)我日常工作以及閱讀源碼必備的 IntelliJ IDEA 高級(jí)調(diào)試技巧,分分鐘要起飛的節(jié)奏

        ?01?Stream Trace

        自從 Java 8 開始,作為程序員的我們都離不開 Stream 相關(guān)功能的使用,書寫起來那叫一個(gè)流暢(這個(gè) feel~~)。但總是有一些時(shí)候,我們對(duì) stream 的操作所要的結(jié)果和預(yù)期不符,這就需要我們逐步調(diào)試,定位問題。

        常規(guī)調(diào)試

        先來看下面這段代碼:

        public?static?void?main(String[]?args)?{
        ??Object[]?res?=?Stream.of(1,2,3,4,5,6,7,8).filter(?i?->?i%2?==?0).filter(?i?->?i>3).toArray();
        ??System.out.println(Arrays.toString(res));
        }

        我們可以在 Stream 操作處打上斷點(diǎn),逐步查看結(jié)果,就像這樣:

        我們需要各種單步調(diào)試,不是很直觀,我們迫切的需要個(gè)一覽視圖,讓我們快速查看我們的 Stream 結(jié)果

        可視化調(diào)試

        同樣先選擇行斷點(diǎn),以?Debug?模式進(jìn)入程序:

        接下來會(huì)彈出?Stream Trace,整個(gè) Stream 操作盡顯眼前

        同樣可以點(diǎn)擊左下角的?Flat Mode?按鈕,將整個(gè)視圖扁平化

        在實(shí)際業(yè)務(wù)中,我們通常對(duì)集合進(jìn)行各種 Stream 操作,我們?cè)賮韨€(gè)復(fù)雜一些的例子:

        ??List>?customers?=?Arrays.asList(
        ????Optional.of(new?Customer("日拱一兵",?18)),
        ????Optional.of(new?Customer("卑微的小開發(fā)",?22)),
        ????Optional.empty(),
        ????Optional.of(new?Customer("OOT",?21)),
        ????Optional.empty(),
        ????Optional.of(new?Customer("溫柔一刀",?23)),
        ????Optional.empty()
        ??);

        ??long?numberOf65PlusCustomers?=?customers
        ????.stream()
        ????.flatMap(c?->?c
        ??????.map(Stream::of)
        ??????.orElseGet(Stream::empty))
        ????.filter(c?->?c.getAge()?>?18)
        ????.count();

        ??System.out.println(numberOf65PlusCustomers);

        同樣按照上面的操作得到可視化 Stream Trace 視圖,直觀了解整個(gè) Stream 流程,查看對(duì)象屬性等


        02 斷點(diǎn)處添加 log

        很多程序員在調(diào)試代碼時(shí)都喜歡 print 一些內(nèi)容,這樣看起來更直觀,print 完之后又很容易忘記刪除掉這些沒用的內(nèi)容,最終將代碼提交到 remote,code review 時(shí)又不得不刪減這些內(nèi)容重新提交,不但增加不必要的工作量,還讓 log tree 的一些節(jié)點(diǎn)沒有任何價(jià)值

        IntelliJ IDEA 提供 Evaluate and Log at Breakpoints 功能恰巧可以幫助我們解決這個(gè)問題, 來看下面代碼:

        public?static?void?main(String[]?args)?{
        ??ThreadLocalRandom?random?=?ThreadLocalRandom.current();
        ??int?count?=?0;
        ??for?(int?i?=?0;?i?5;?i++)?{
        ???if?(isInterested(random.nextInt(10)))?{
        ????count++;
        ???}
        ??}
        ??System.out.printf("Found?%d?interested?values%n",?count);
        ?}



        ?private?static?boolean?isInterested(int?i)?{
        ??return?i?%?2?==?0;
        ?}

        假如我們想在第 15 行查看每次調(diào)用,隨即出來的 i 的值到底是多少,我們沒必要在這個(gè)地方添加任何 log,在正常加斷點(diǎn)的地方使用快捷鍵 Shift + 鼠標(biāo)左鍵,就會(huì)彈出下面的內(nèi)容

        勾選上 Evaluate and log, 并自定義你想查看的 log/變量,比如這里的 "interested" + i, 這樣以 Debug 模式運(yùn)行程序(正常模式運(yùn)行,不會(huì)打印這些 log):

        interested?7
        interested?5
        interested?1
        interested?2
        interested?0
        Found?2?interested?values

        如果你在多處添加了這種斷點(diǎn),簡單的看 log 可能偶爾還是不夠直觀,可以勾選上面圖片綠色框線的 "Breakpoint hit" message :

        Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
        interested?6
        Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
        interested?0
        Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
        interested?9
        Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
        interested?8
        Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
        interested?1
        Found?3?interested?values
        Disconnected?from?the?target?VM,?address:?'127.0.0.1:0',?transport:?'socket'

        Process?finished?with?exit?code?

        如果你想要更詳細(xì)的信息,那就勾選上 Stack trace (大家自己查看運(yùn)行結(jié)果吧),有了這個(gè)功能,上面說的一些問題都不復(fù)存在了

        03 字段斷點(diǎn)

        如果你閱讀源碼,你一定會(huì)有個(gè)困擾,類中的某個(gè)字段的值到底是在哪里改變的,你要一點(diǎn)點(diǎn)追蹤調(diào)用棧,逐步排查,稍不留神,就可能有遺漏

        我們可以在 IntelliJ IDEA 中為某個(gè)字段添加斷點(diǎn),當(dāng)字段值有修改時(shí),自動(dòng)跳到相應(yīng)方法位置

        使用起來很簡單:

        1. 在字段定義處鼠標(biāo)左鍵添加斷點(diǎn)(會(huì)出現(xiàn)「眼睛」的圖標(biāo))
        2. 在「眼睛」圖標(biāo)上鼠標(biāo)右鍵
        3. 在彈框中勾選上 Field accessField modification 兩個(gè)選項(xiàng)

        如果修改字段值的方法比較多,也可以在 Condition 的地方定義斷點(diǎn)進(jìn)入條件, 有了這個(gè)功能的加成,相信你閱讀源碼會(huì)順暢許多

        04 異常斷點(diǎn)

        除了閱讀源碼,一定是遇到了異常我們才開始調(diào)試代碼,代碼在拋出異常之后會(huì)自動(dòng)停止,但是我們希望:

        代碼停在拋出異常之前,方便我們查看當(dāng)時(shí)的變量信息

        這時(shí)我們就用到了 Exception Breakpoints, 當(dāng)拋出異常時(shí),在 catch 的地方打上斷點(diǎn),可以通過下圖的幾個(gè)位置獲取棧頂異常類型,比如這里的 NumberFormatException

        知道異常類型后,就可以按照如下步驟添加異常斷點(diǎn)了:

        然后在彈框中選擇 NumberFormatException

        重新以 Debug 模式運(yùn)行程序:

        程序「一路綠燈式」定位到拋出異常的位置,同時(shí)指出當(dāng)時(shí)的變量信息,三個(gè)字:穩(wěn),準(zhǔn),狠,還有誰?

        05 方法斷點(diǎn)

        當(dāng)閱讀源碼時(shí),比如 Spring,一個(gè)接口的方法可能被多個(gè)子類實(shí)現(xiàn),當(dāng)運(yùn)行時(shí),需要查看調(diào)用棧逐步定位實(shí)現(xiàn)類,IDEA 同樣支持在接口方法上添加斷點(diǎn)(快捷鍵 cmd+F8/ctrl+F8):

        1. 鼠標(biāo)左鍵在方法處點(diǎn)擊斷點(diǎn)(??形狀)
        2. 斷點(diǎn)上鼠標(biāo)右鍵

        勾選上綠色框線上的內(nèi)容,同樣可以自定義跳轉(zhuǎn)條件 Condition

        當(dāng)以 Debug 模式運(yùn)行程序的時(shí)候,會(huì)自動(dòng)進(jìn)入實(shí)現(xiàn)類的方法(注意斷點(diǎn)形狀):

        看到這你應(yīng)該想到常見的 Runnable 接口中的 run 方法了,同樣是有作用的,大家可以自行去嘗試了

        總結(jié)

        相信有以上四種調(diào)試技巧的加成,無論是工作 debug 還是閱讀源碼,都可以輕松駕馭了。最后,來看看 IDEA 支持的各種斷點(diǎn)調(diào)試類型。


        如有文章對(duì)你有幫助,

        在看”和轉(zhuǎn)發(fā)是對(duì)我最大的支持!

        一款牛逼的Java面試題庫,點(diǎn)擊下圖查看詳細(xì)內(nèi)容

        瀏覽 58
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            蜜芽亚洲无码 | 欧美老熟妇乱大交XXXXX www.91av | 婷婷亚洲色| 日韩无码黄片 | 久久久99精品免费观看app | 人妻无码一区二区三区 | 操逼视频免费的 | 精品久久无码 | tickling挠裸乳尿孔网站 | 女生扒开裙子让男生c |