作者:bojiangzhou, 來源:www.cnblogs.com/chiangchou/p/idea-debug.html
ebug用來追蹤代碼的運行流程,通常在程序運行過程中出現(xiàn)異常,啟用Debug模式可以分析定位異常發(fā)生的位置,以及在運行過程中參數(shù)的變化。通常我們也可以啟用Debug模式來跟蹤代碼的運行流程去學習三方框架的源碼。
所以學習下如何在Intellij IDEA中使用好Debug。
一、Debug開篇
首先看下IDEA中Debug模式下的界面。
如下是在IDEA中啟動Debug模式,進入斷點后的界面,我這里是Windows,可能和Mac的圖標等會有些不一樣。就簡單說下圖中標注的8個地方:
1、以Debug模式啟動服務,左邊的一個按鈕則是以Run模式啟動。在開發(fā)中,我一般會直接啟動Debug模式,方便隨時調(diào)試代碼。
2、斷點:在左邊行號欄單擊左鍵,或者快捷鍵Ctrl+F8 打上/取消斷點,斷點行的顏色可自己去設(shè)置。
3、Debug窗口:訪問請求到達第一個斷點后,會自動激活Debug窗口。如果沒有自動激活,可以去設(shè)置里設(shè)置,如圖1.2。
4、調(diào)試按鈕:一共有8個按鈕,調(diào)試的主要功能就對應著這幾個按鈕,鼠標懸停在按鈕上可以查看對應的快捷鍵。在菜單欄Run里可以找到同樣的對應的功能,如圖1.4。
5、服務按鈕:可以在這里關(guān)閉/啟動服務,設(shè)置斷點等。
6、方法調(diào)用棧:這里顯示了該線程調(diào)試所經(jīng)過的所有方法,勾選右上角的[Show All Frames]按鈕,就不會顯示其它類庫的方法了,否則這里會有一大堆的方法。
7、Variables:在變量區(qū)可以查看當前斷點之前的當前方法內(nèi)的變量。
8、Watches:查看變量,可以將Variables區(qū)中的變量拖到Watches中查看
[圖1.1]
在設(shè)置里勾選Show debug window on breakpoint,則請求進入到斷點后自動激活Debug窗口
[圖1.2]
如果你的IDEA底部沒有顯示工具欄或狀態(tài)欄,可以在View里打開,顯示出工具欄會方便我們使用。可以自己去嘗試下這四個選項。
[圖1.3]
在菜單欄Run里有調(diào)試對應的功能,同時可以查看對應的快捷鍵。
[圖1.4]
二、基本用法&快捷鍵
Debug調(diào)試的功能主要對應著圖一中4和5兩組按鈕:
1、首先說第一組按鈕,共8個按鈕,從左到右依次如下:
[圖2.1]
2、第二組按鈕,共7個按鈕,從上到下依次如下:
[圖2.2]
更新程序,On 'Update' actions,執(zhí)行更新操作時所做的事情,一般選擇'Update classes and resources',即更新類和資源文件。
一般配合熱部署插件會更好用,如JRebel,這樣就不用每次更改代碼后還要去重新啟動服務。如何激活JRebel,在最后章節(jié)附上。
下面的On frame deactivation,在IDEA窗口失去焦點時觸發(fā),即一般你從idea切換到瀏覽器的時候,idea會自動幫你做的事情,一般可以設(shè)置Do nothing,頻繁切換會比較消耗資源的。
[圖2.3]
[圖2.4]
三、變量查看
在Debug過程中,跟蹤查看變量的變化是非常必要的,這里就簡單說下IDEA中可以查看變量的幾個地方,相信大部分人都了解。
1、如下,在IDEA中,參數(shù)所在行后面會顯示當前變量的值。
[圖3.1]
2、光標懸停到參數(shù)上,顯示當前變量信息。點擊打開詳情如圖3.3。我一般會使用這種方式,快捷方便。
[圖3.2]
[圖3.3]
3、在Variables里查看,這里顯示當前方法里的所有變量。
[圖3.4]
4、在Watches里,點擊New Watch,輸入需要查看的變量。或者可以從Variables里拖到Watche里查看。
[圖3.5]
如果你發(fā)現(xiàn)你沒有Watches,可能在下圖所在的地方。
[圖3.6]
[圖3.7]
四、計算表達式
在前面提到的計算表達式如圖4.1的按鈕,Evaluate Expression (Alt + F8) 。可以使用這個操作在調(diào)試過程中計算某個表達式的值,而不用再去打印信息。
[圖4.1]
1、按Alt + F8或按鈕,或者,你可以選中某個表達式再Alt + F8,彈出計算表達式的窗口,如下,回車或點擊Evaluate計算表達式的值。
這個表達式不僅可以是一般變量或參數(shù),也可以是方法,當你的一行代碼中調(diào)用了幾個方法時,就可以通過這種方式查看查看某個方法的返回值。
[圖4.2]
2、設(shè)置變量,在計算表達式的框里,可以改變變量的值,這樣有時候就能很方便我們?nèi)フ{(diào)試各種值的情況了不是。
[圖4.3]
五、智能步入
想想,一行代碼里有好幾個方法,怎么只選擇某一個方法進入。之前提到過使用Step Into (Alt + F7) 或者 Force Step Into (Alt + Shift + F7)進入到方法內(nèi)部,但這兩個操作會根據(jù)方法調(diào)用順序依次進入,這比較麻煩。
那么智能步入就很方便了,智能步入,這個功能在Run里可以看到,Smart Step Into (Shift + F7),如圖5.1
[圖5.1]
按Shift + F7,會自動定位到當前斷點行,并列出需要進入的方法,如圖5.2,點擊方法進入方法內(nèi)部。
果只有一個方法,則直接進入,類似Force Step Into。
[圖5.2]
六、斷點條件設(shè)置
通過設(shè)置斷點條件,在滿足條件時,才停在斷點處,否則直接運行。
通常,當我們在遍歷一個比較大的集合或數(shù)組時,在循環(huán)內(nèi)設(shè)置了一個斷點,難道我們要一個一個去看變量的值?那肯定很累,說不定你還錯過這個值得重新來一次。
1、在斷點上右鍵直接設(shè)置當前斷點的條件,如圖6.1,我設(shè)置exist為true時斷點才生效。
[圖6.1]
2、點擊View Breakpoints (Ctrl + Shift + F8),查看所有斷點。
[圖6.2]
[圖6.3]
3、再說說右邊的Filters過濾,這些一般情況下不常用,簡單說下意思。
[圖6.4]
[圖6.5]
4、異常斷點,通過設(shè)置異常斷點,在程序中出現(xiàn)需要攔截的異常時,會自動定位到異常行。
如圖6.6,點擊+號添加Java Exception Breakpoints,添加異常斷點。然后輸入需要斷點的異常類,如圖6.7,之后可以在Java Exception Breakpoints里看到添加的異常斷點。
我這里添加了一個NullPointerException異常斷點,如圖6.8,出現(xiàn)空指針異常后,自動定位在空指針異常行。
[圖6.6]
[圖6.7]
[圖6.8]
七、多線程調(diào)試
一般情況下我們調(diào)試的時候是在一個線程中的,一步一步往下走。但有時候你會發(fā)現(xiàn)在Debug的時候,想發(fā)起另外一個請求都無法進行了?
那是因為IDEA在Debug時默認阻塞級別是ALL,會阻塞其它線程,只有在當前調(diào)試線程走完時才會走其它線程。可以在View Breakpoints里選擇Thread,如圖7.1,然后點擊Make Default設(shè)置為默認選項。
[圖7.1]
切換線程,在圖7.2中Frames的下拉列表里,可以切換當前的線程,如下我這里有兩個Debug的線程,切換另外一個則進入另一個Debug的線程。
[圖7.2]
八、回退斷點
在調(diào)試的時候,想要重新走一下流程而不用再次發(fā)起一個請求?
1、首先認識下這個方法調(diào)用棧,如圖8.1,首先請求進入DemoController的insertDemo方法,然后調(diào)用insert方法,其它的invoke我們且先不管,最上面的方法是當前斷點所在的方法。
[圖8.1]
2、斷點回退
所謂的斷點回退,其實就是回退到上一個方法調(diào)用的開始處,在IDEA里測試無法一行一行地回退或回到到上一個斷點處,而是回到上一個方法。
回退的方式有兩種,一種是Drop Frame按鈕(圖8.2),按調(diào)用的方法逐步回退,包括三方類庫的其它方法(取消Show All Frames按鈕會顯示三方類庫的方法,如圖8.3)。
第二種方式,在調(diào)用棧方法上選擇要回退的方法,右鍵選擇Drop Frame(圖8.4),回退到該方法的上一個方法調(diào)用處,此時再按F9(Resume Program),可以看到程序進入到該方法的斷點處了。
但有一點需要注意,斷點回退只能重新走一下流程,之前的某些參數(shù)/數(shù)據(jù)的狀態(tài)已經(jīng)改變了的是無法回退到之前的狀態(tài)的,如對象、集合、更新了數(shù)據(jù)庫數(shù)據(jù)等等。
圖[8.2]
圖[8.3]
圖[8.4]
九、中斷Debug
想要在Debug的時候,中斷請求,不要再走剩余的流程了?
有些時候,我們看到傳入的參數(shù)有誤后,不想走后面的流程了,怎么中斷這次請求呢(后面的流程要刪除數(shù)據(jù)庫數(shù)據(jù)呢....),難道要關(guān)閉服務重新啟動程序?嗯,我以前也是這么干的。
確切的說,我也沒發(fā)現(xiàn)可以直接中斷請求的方式(除了關(guān)閉服務),但可以通過Force Return,即強制返回來避免后續(xù)的流程,如圖9.1。
點擊Force Return,彈出Return Value的窗口,我這個方法的返回類型為Map,所以,我這里直接返回 results,來強制返回,從而不再進行后續(xù)的流程。或者你可以new HashMap<>()。
[圖9.1]
[圖9.2]
家好,我是DD,已經(jīng)是封閉在家的第51天了!
最近一直在更新Java新特性(https://www.didispace.com/java-features/)和IDEA Tips(https://www.didispace.com/idea-tips/)兩個原創(chuàng)專欄,其他方向內(nèi)容的動態(tài)關(guān)注少了。昨天天晚上刷推的時候,瞄到了這個神奇的東西,覺得挺cool的,拿出來分享下:
相信你看到圖,不用我說,你也猜到是啥了吧?html里可以跑python代碼了!
看到好多Python公眾號已經(jīng)開始猛吹未來了,但乍看怎么覺得有點像JSP?或者一些模版引擎?是進步還是倒退呢?與其瞎想,不如仔細看看這個東東的能力吧!
根據(jù)官方介紹,這個名為PyScript的框架,其核心目標是為開發(fā)者提供在標準HTML中嵌入Python代碼的能力,使用 Python調(diào)用JavaScript函數(shù)庫,并以此實現(xiàn)利用Python創(chuàng)建Web應用的功能。
看到介紹里提到了調(diào)用JavaScript函數(shù)庫的能力,看來跟JSP或者模版引擎還是有區(qū)別的。
官方給了一個例子,可以幫助我們觀的感受這個開發(fā)框架的能力,不妨跟著DD看看,它能做啥吧!
第一個案例,hello world
代碼很簡單,就下面這幾行。你只需要創(chuàng)建一個html文件,然后復制進去就可以了。
|
保存好之后,在瀏覽器里打開就能看到這樣的頁面了:
回頭再看看這個html里的內(nèi)容,三個核心內(nèi)容:
如果你懶得自己敲代碼的話,本文的兩個案例代碼我打包放在公眾號了,需要的朋友可以關(guān)注公眾號“程序猿DD”,回復:pyscript 獲取。
第二個案例,數(shù)據(jù)定義 + 數(shù)據(jù)展示
先創(chuàng)建一個data.py文件,然后加入前面的代碼。功能很簡單,就是隨機生成(x,y)的坐標
|
再創(chuàng)建一個html文件,加入下面的代碼
|
這里就稍微復雜一些了,除了hello world中的幾個要點外,這里還有這幾個要關(guān)注的地方:
這個頁面的執(zhí)行效果是這樣的:
是不是很神奇呢?整個過程中都沒有大家熟悉的cs、js內(nèi)容,就完成了這樣一個圖的頁面實現(xiàn)。
最后,談談在整個嘗試過程中,給我的幾個感受:
這個開發(fā)框架目前還只是alpha版本,未來一定還會有更多特性與優(yōu)化出來,總體上我覺得這個框架還是非常cool的,尤其對于剛學會Python,或者只會Python,但又想快速開發(fā)Web應用的小伙伴來說,可能將會是個不錯的選擇,那你覺得這個框架如何?未來會不會火?留言區(qū)聊聊吧!
擊關(guān)注,快速進階高級架構(gòu)師
作者:G_Seinfeld
工欲善其事,必先利其器。
一款好的IDE(集成開發(fā)環(huán)境,Integrated Development Environment)對于程序員就像一把好的兵器對于武將一樣重要,這句話對于Java這種笨重的語言而言尤其適用。好在Java有了集美貌與智慧于一身的IDE——Intellij IDEA,它就像二爺?shù)某嗤民R和青龍偃月刀一樣在Java世界中奮勇殺敵。如果你在使用Eclipse或者Netbeans之類的IDE,在繼續(xù)閱讀之前我建議你嘗試一下Intellij IDEA,你會愛上它的。如果你已經(jīng)在使用IDEA了,這篇文章會給你一些進階應用的指南,讓你的神兵用起來更加得心應手。今天我們主要介紹一下IDEA的語言注入功能、自定義代碼模板以及簡單的重構(gòu)技巧。
語言注入(language injection)
語言注入是指在Java的字符串里書寫另一種語言時將該語言的特征(高亮、語法檢查等)注入到字符串中。比如,有時我們需要用Java字符串來表達SQL語句、JSON串或者正則表達式。這時我們可以在要注入的字符串中按Alt+Enter,如下圖:
language injection
然后選擇Inject language or reference
select language
比如這里我們選擇JSON,我們可以看到JSON字符串的key部分被高亮了:
json
如果選擇的語言有自動補全的功能,在這里也可以直接使用自動補全功能。如果語法不符合該語言的語法,也會有編譯器的錯誤提示。總之,就像你真的再寫這種語言一樣。但是有一點不爽的是,在字符串里面需要注意轉(zhuǎn)義的事情。IDEA的設(shè)計者顯然也考慮到了這個問題,因此還提供了Edit XXX Fragment的功能,其中XXX是指你注入的語言。
edit fragment
在已經(jīng)注入語言的字符串上再次按Alt+Enter,選擇Edit XXX Fragment,彈出下面的輸入窗,可以在該窗口中直接書寫相應的語言,在上面的字符串中,IDEA會自動替你將該轉(zhuǎn)義的東西轉(zhuǎn)義掉,這點對于寫正則表達式而言特別方便。順便一提,如果你注入的是正則表達式的話,IDEA還提供了Check RegExp功能,用于檢查你指定的字符串與正則表達式是否匹配。
除了使用上面提到的方式進行語言注入外,還可以通過添加注釋的方式進行語言注入,即在需要注入的字符串上方寫入形如
// language=LANG prefix=PRE suffix=SUF
的注釋,其中LANG是你要注入的語言,prefix和suffix分別是指定的前后綴,如果沒有可以省略。如果你的字符串表達的不是一個完整的語言片段,可以通過前后綴的拼接使其形成一個完整的語言片段,如下圖的html示例:
comment injection
自定義代碼模板(live templates)
live templates是IDEA中提高代碼編寫速度,減少重復性工作的又一大利器。用過IDEA的人應該基本都使用過內(nèi)置的代碼模板,只不過可能不知道而已。下面列舉幾個常用的live templates:
是public static void main的縮寫,依次敲入這幾個字母可以在一個類中快速生成main方法。
public static void main(String[] args) { }
用于快速生成輸出語句
System.out.println();
用于快速生成字符串常量
public static final String
for (int i=0; i < ; i++) { }
用于快速生成增強for循環(huán)代碼,其中要遍歷的對象以及元素類型可以推斷,元素對象名稱可以推薦。
for (String key : map.keySet()) { }
用于生成判空的條件判斷語句,判斷的對象自動推斷
if (s==null) { }
用于生成判斷非空的條件判斷語句,判斷的對象自動推斷
if (s !=null) { }
這些官方提供的內(nèi)置模板已經(jīng)足夠nice,但是可能不能充分滿足我們自己特殊場景的使用。我們可以根據(jù)自身使用的情況DIY我們自己的模板。那么怎么定義我們自己的代碼模板呢?
首先按Ctrl+Alt+S打開設(shè)置(或者點擊File-Settings),找到Editor下的Live Templates選項,進入自定義模板頁面。
live templates
這里默認是按照語言和用途分的組,我們可以新增自己的模板組,點擊右上角的小加號,選擇template group即可。接下來是在已有組中增加模板,點擊右上角的小加號,選擇live template。或者利用現(xiàn)有的模板進行duplicate(右上角第三個按鈕)也可以。比如我們新建一個待辦事項的注釋,想要指定用戶和時間:
todo
我們首先增加一個自定義模板組comment,在下面添加一個todo模板,在Abbreviation(縮寫)里面寫入todo,即寫代碼時要輸入的模板簡寫,在右邊description中輸入模板的描述信息,在下面Template text中寫入模板內(nèi)容:
//TODO $DATE$ $USER$: $END$
其中//TODO是Java中待辦事項的注釋,后面DATE和USER是自定義的變量,分別代表日期和用戶,END是IDEA內(nèi)置的變量,代表生成模板后光標所處的位置。很容易想到,兩個美元符號$$中間加上大寫字母是模板中定義變量的方式。那么這些變量怎么取值呢,我們點擊右側(cè)的Edit variables按鈕,就可以看到這樣的界面:
edit variables
這里可以看到DATE和USER變量的取值,分別為date()和user(),date()和user()是IDEA內(nèi)置的兩個函數(shù),用于表征當前時間和當前系統(tǒng)用戶,如果Expression(表達式)項沒有取到值,我們還可以在Default value中設(shè)置默認值,不過不是所有項都可以走默認值的,勾選右邊的復選框代表如果變量取到確切值,光標直接跳過此處。IDEA提供了幾十個內(nèi)置函數(shù),用于處理模板中的各種情況,內(nèi)置函數(shù)的完整列表可以參見官方文檔
(https://www.jetbrains.com/help/idea/template-variables.html#predefined_functions)。
重構(gòu)是編寫代碼的一個重要環(huán)節(jié),它是在基本不改變代碼語義的前提下,對代碼直觀性、可讀性以及代碼邏輯層次進行的改造。重構(gòu)的技巧非常多,大牛們經(jīng)常花一本書的內(nèi)容來介紹重構(gòu)。這里我們只介紹怎么在IDEA中方便地進行常見的代碼重構(gòu)。首先先普及一樣IDEA中萬能重構(gòu)的快捷鍵:Ctrl+Alt+Shift+T,一切重構(gòu)都可以以此為入口。在IDEA中最常用的重構(gòu)主要包括重命名(rename)、代碼提取(extract)、代碼嵌入(inline)。
重命名,或者叫改名。有時候我們會覺得類、方法、變量名稱不能準確表達我們要傳遞給讀者的含義,此時我們就需要重命名。IDEA中重命名的快捷鍵是Shift+F6,當然也可以從萬能入口進入。重命名后所有調(diào)用之處會自動修改引用的名稱。
代碼提取,可以指從實現(xiàn)類中提取接口或父類,也可以指從代碼中提取方法。下面說一些常見的場景:
鏈接:https://www.jianshu.com/p/cc08f90a5102
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。