《Java 核心技术卷1 第10版》学习笔记------调试技巧
調試器是 Eclipse 、 NetBeans 這類專業集成開發環境的一部分 。 在啟動調試器之前, 本節先給出一些有價值的建議 。
1 ) 可以用下面的方法打印或記錄任意變量的值 :
2 ) 一個不太為人所知但卻非常有效的技巧是在每一個類中放置一個單獨的 main 方法 。這樣就可以對每一個類進行單元測試 。
public class MyClass {methods and fields...public static void main ( String[] args){test code} }3) 使用單元測試框架例如 JUnit
4) 日志代理(logging proxy)是一個子類對象,他可以截獲方法按調用,并進行日志記錄,然后調用超類中的方法。例如,如果在調用 Random 類的 nextDouble 方法時出現了問題,就可以按照下面的方式,以匿名子類實例的形式創建一個代理對象:
public static void main(String[] args){Random generator = new Random(){@Overridepublic double nextDouble() {double result = super.nextDouble();Logger.getGlobal().info("nextDouble: " + result);return result;}};System.out.println(generator.nextDouble());}當調用 nextDouble 方法時 , 就會產生一個日志消息 。 要想知道誰調用了這個方法, 就要生成一個堆棧軌跡 。
運行結果:
5. 利用 Throwable 類提供的 pringStackTrace 方法,可以從任何一個異常對象中獲得堆棧情況。下面的代碼將捕獲任何異常,打印異常對象和堆棧軌跡,然后,重新拋出異常,以便能夠找到相應的處理器。
try{... }catch(Throwable t){t.printStackTrace();throw t; }不一定要通過捕獲異常來生成堆棧軌跡。只要在代碼的任何位置插入下面這條語句就可以獲得堆棧軌跡:
Thread.dumpStack();6) 一般來說,堆棧軌跡顯示在 System.err 上。也可以利用printStackTrace(PrintWriter s)方法將它發送到一個文件中。另外,如果想記錄或者顯示堆棧軌跡,就可以采用下面的方式,將它捕獲到一個字符串中:
StringWriter out = new StringWriter(); new Throwable().printStackTrace(new PrintWriter(out)); String description = out.toString;7) 通常,將一個程序的錯誤信息保存在一個文件中是非常有用的。然而,錯誤信息被送到 System.err 中,而不是 System.out 中。因此,不能夠通過運行下面的語句獲取它們:
java MyProgram > errors.txt // 這里只是將標注輸出【即 System.out】內容重定向到 errors.txt 中 // 正確的做法是 java MyProgram 2> errors.txt // 這里就是將標準出錯【即 System.out】 內容重定向到 errors.txt// 要想在同一個文件中同時捕獲 System.out 和 System.err,需要這樣做 java MyProgram 1> errors.txt 2>&1 // 1> errors.txt 表示將 System.out 重定向到 errors.txt;2>&1 表示將 System.err 重定向到 System.out 中// 上述命令將在bash 和 windows shell 中運行 // PS: 操作系統一般都有這三個三個I/O,分別是標準輸入、標準輸出、標準出錯。分別對應Java中的 System.in System.out System.err // “>" 重定向符號 ">>" 可以追加的重定向8) 讓非捕獲異常[即運行時異常 RuntimeException,非檢查異常]的棧軌跡出現在 System.err 中并不是一個很理想的方法。如果在客戶端偶然看到這些消息,則會感到迷惑,而且在需要的時候也無法實現診斷目的。比較好的方式是將這些內容記錄到一個文件中。keyi調用靜態的 Thread.setDefaultUncaughtExceptionHandler 方法改變非捕獲異常的處理器。
new Thread.UncaughtExceptionHandler(){@Overridepublic void uncaughtException(Thread t, Throwable e) {// save information in log fileLogger.getGlobal().throwing("com.mycompany.myapp", "main", e);} }9) 要想觀察類的加載過程,可以用 -verbose 標志啟動 Java 虛擬機。這樣就可以看到如下所出書結果:
有時候 , 這種方法有助于診斷由于類路徑引發的問題 。
10 )?-Xlint 選項告訴編譯器對一些普遍容易出現的代碼問題進行檢査?。 例如 , 如果使用下面這條命令編譯 :
javac -Xlint : fallthrough
當 switch 語句中缺少 break 語句時 , 編譯器就會給出報告(術語 “ lint ” 最初用來描述一種定位 C 程序中潛在問題的工具 , 現在通常用于描述查找可疑但不違背語法規則的代碼問題的工具 。 )
下面列出了可以使用的選項 :
11)?java 虛擬機增加了對 Java 應用程序進行監控 (monitoring ) 和管理 ( management ) 的支持 。 它允許利用虛擬機中的代理裝置跟蹤內存消耗 、 線程使用 、 類加載等情況 。 這個功能對于像應用程序服務器這樣大型的 、 長時間運行的 Java 程序來說特別重要 。 下面是一個能夠展示這種功能的例子 : JDK 加載了一個稱為 jconsole 的圖形工具 , 可以用于顯示虛擬機性能的統計結果, 如圖 7 -3 所示 。 找出運行虛擬機的操作系統進程的 ID 。 在 UNIX / Linux 環境下 ,運行 ps 實用工具, 在 Windows 環境下, 使用任務管理器 。 然后運行 jconsole 程序 :
jconsole processID【即進程ID】
控制臺給出了有關運行程序的大量信息 。有關更加詳細的信息參見 www.orade.com/technetwork/articles/java/jconsole-1564139.html
12)?可以使用 jmap 實用工具獲得一個堆的轉儲 , 其中顯示了堆中的每個對象 。 使用命令如下 :
jmap -dump:format=b,file=dumpFileName processID
jhat dumpFileName
然后 , 通過瀏覽器進人localhost:7000 , 將會運行一個網絡應用程序 , 借此探查轉儲對象時堆的內容 。
13 ) 如果使用 -Xprof 標志運行 Java 虛擬機, 就會運行一個基本的剖析器來跟蹤那些代碼中經常被調用的方法 。 剖析信息將發送給 System . out 。 輸出結果中還會顯示哪些方法是由即時編譯器編譯的 。
?
總結
以上是生活随笔為你收集整理的《Java 核心技术卷1 第10版》学习笔记------调试技巧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Java 核心技术卷1 第10版》学习
- 下一篇: 《Java 核心技术卷1 第10版》学习