項目php |
內容html |
這個做業屬於哪一個課程java |
|
這個做業的要求在哪裏typescript |
https://www.cnblogs.com/nwnu-daizh/p/11778090.html數據庫 |
做業學習目標編程 |
1.掌握java異常處理技術;數組 2.瞭解斷言的用法;緩存 3.瞭解日誌的用途;安全 4.掌握程序基礎調試技巧。 |
第一部分:總結第七章關於異常處理相關理論知識
一、檢查性異常:
(1)最具表明性的檢查性異常是用戶錯誤或問題引發的異常,這是程序員沒法預測的。 (2)例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單的忽略。
二、運行時異常:
(1)運行時異常是可能被程序員避免的異常。 (2)與檢查性異常相反,運行時異常能夠在編譯時被忽略。
三、錯誤:
(1)錯誤不是異常,而是脫離程序員控制的問題。 (2)錯誤在代碼中一般被忽略。 (3)例如,當棧溢出時,一個錯誤就發生了,它們在編譯時也是檢查不到的。
四、異常分類圖解:
Error類:
(1)Error類以及他的子類的實例,表明了JVM自己的錯誤。 (2)錯誤不能被程序員經過代碼處理,Error不多出現。 (3)所以,程序員應該關注Exception爲父類的分支下的各類異常類
Exception類:
(1)Exception及他的子類,表明程序運行時發送的各類不指望發生的事件。 (2)能夠被java異常處理機制使用,是異常處理的核心。
RuntimeException
,另外一類就是其餘異常。由於RuntimeException
是由Java
虛擬機自動拋出並自動捕獲,因此又叫非檢查異常
。而另外一類異常就不同了,須要咱們手動的捕獲和處理異常,因此叫作檢查異常
。在編寫代碼處理異常時,對於檢查異常,有兩種處理方式:
(1)使用try...catch...finally語句塊處理 (2)在函數簽名中使用throws聲明交給函數調用者caller去解決
五、try...catch...finally語句塊:
(1)try塊中放可能發生異常的代碼;
(2)若是執行完try而且不發生異常,則接着去執行finally塊代碼以及finally以後的代碼;
(3)若是執行try中代碼發生異常,就會嘗試匹配catch塊;
(4)每個catch塊用於處理一個異常;
(5)異常匹配是按照catch塊的順序從上往下尋找的,只有第一個會匹配到的catch塊會被執行。
(6)try塊中的局部變量和catch塊中的局部變量,以及finally中的局部變量,它們之間不能夠共享使用;
(7)finally塊無論異常是否發生,只要對應的try塊執行了,它必定會執行。
(8)finally塊一般用來作資源釋放操做,關閉文件或者關閉數據庫等操做。
六、throws/throw:
(1)若是一個方法沒有捕獲到一個檢查性異常,那麼該方法必須使用 throws 關鍵字來聲明。
(2)throws 關鍵字放在方法簽名的尾部。
(3)throws僅僅是將函數中可能出現的異常向調用者聲明,而本身並不處理異常。
(4)採用這種異常處理的緣由多是:方法自己不知道如何處理這種異常,或者說讓調用者處理更好,調用者須要爲可能發生的異常負責。
(5)也可使用 throw 關鍵字手動拋出一個異常,不管它是新實例化的仍是剛捕獲到的。
(6)throw語句的後面必須是一個異常對象。
若是沒有咱們使用最原始的解決異常是個什麼辦法:
而後 有了能表示全部的異常狀況而後處理掉 try...catch
若是try塊
裏的業務邏輯代碼出現了異常,系統就會生成一個異常對象,而後將該對象提交給Java運行時環境
(throw),接着查找catch塊
,若是找到了合適的catch塊
,就將該異常對象交由該catch塊處理。這個過程又叫作捕獲(catch)異常
;若是找不到合適的catch塊
,程序將退出。
finally,最終的,也就是咱們處理完異常最後要作的事情。因爲有時候咱們會在try塊
裏面使用一些資源,這些資源最後也就在finally塊
裏被回收掉了。
對於一個完整的應用而言,都是有比較嚴格的分層關係的,上層依賴下層的API
。而對於用戶而言,咱們不想看到底層的SQL異常
,同時也會使得系統不安全。因此這時咱們就要將底層的異常捕獲,而後再拋出一個新的業務異常,就能夠在新的異常中給出用戶比較友好的提示信息。
或者咱們也能夠這樣處理異常:
這是因爲Throwable
基類有了一個能夠接受Exception
參數的方法。
雖然java已經提供了不少系統性異常,但在開發中仍是沒法知足實際的須要。因此java容許用戶自定義異常。語法以下:
2、實驗內容和步驟
實驗1:用命令行與IDE兩種環境下編輯調試運行源程序ExceptionDemo1、ExceptionDemo2,結合程序運行結果理解程序,掌握未檢查異常和已檢查異常的區別。
示例1代碼:
package project7; //異常示例1 public class ExceptionDemo1 { public static void main(String args[]) { int a = 0; System.out.println(5 / a); } } // 線程中的異常爲 ArithmeticException 算術異常 //代碼錯誤 5/0 (ExceptionDemo1.java:6) //此異常爲Throwable類中的子類Exception(RuntimeException/unchecked Exception) //未檢查異常 //編譯器不要求強制處理的異常,雖然有可能出現錯誤,但不會再編譯的時候檢查 //此算術異常是由程序員失誤形成的,編譯器沒編譯以前根本不知道會出現這種錯誤。 //這種不能被直接檢查出的錯誤被稱爲非檢查型異常,便是不能被try catch捕獲的異常
運行:
示例2代碼:
package project7; //異常示例2 import java.io.*; public class ExceptionDemo2 { public static void main(String args[]) { FileInputStream fis=new FileInputStream("text.txt");//JVM自動生成異常對象 int b; while((b=fis.read())!=-1) { System.out.print(b); } fis.close(); } } //線程中出現的異常: 未解決的編譯問題 //異常類型:FileNotFoundException/ IOException //出現異常處:(ExceptionDemo2.java:8) //已檢查異常 //編譯器要求你必須處理的異常(代碼還沒運行,編譯器就會檢查你的代碼,會不會出現異常,要求你對可能出現的異常必須作出相應的處理) //編譯器要求你對這段代碼 try...catch,或者throws exception /* 對已檢查異常的處理: * 一、繼續拋出,消極的方法,一直能夠拋到java虛擬機來處理,就是經過throws exception拋出。 * 二、用try...catch捕獲 * 注意:對於檢查的異常必須處理,或者必須捕獲或者必須拋出 * */
運行:
實驗2: 導入如下示例程序,測試程序並進行代碼註釋。
測試程序1:
在elipse IDE中編輯、編譯、調試運行教材281頁7-1,結合程序運行結果理解程序;
在程序中相關代碼處添加新知識的註釋;
掌握Throwable類的堆棧跟蹤方法;
代碼:
package stackTrace; import java.util.*; /** * A program that displays a trace feature of a recursive method call. * @version 1.10 2017-12-14 * @author Cay Horstmann */ public class StackTraceTest { /** * Computes the factorial of a number * @param n a non-negative integer * @return n! = 1 * 2 * . . . * n */ public static int factorial(int n) { System.out.println("factorial(" + n + "):"); Throwable t = new Throwable(); //調用Throwable類的getStackTrace方法訪問堆棧軌跡的文本描述信息 StackTraceElement[] frames = t.getStackTrace(); //獲得StackTraceElement對象的一個數組,並在程序中分析這個對象數組 for(StackTraceElement f:frames) System.out.println(f); int r; if (n <= 1) r = 1; else r = n * factorial(n - 1); System.out.println("return " + r); return r; } public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.print("Enter n: "); int n = in.nextInt(); factorial(n); in.close(); } }
運行:
測試程序2:
Java語言的異常處理有積極處理方法和消極處理兩種方式;
下列兩個簡單程序範例給出了兩種異常處理的代碼格式。在elipse IDE中編輯、調試運行源程序ExceptionTest.java,將程序中的text文件更換爲身份證號.txt,要求將文件內容讀入內容,並在控制檯顯示;
掌握兩種異常處理技術的特色。
代碼1:
package project7; //積極處理方式 import java.io.*; class ExceptionTest1 { public static void main (String args[]) { try{ FileInputStream fis=new FileInputStream("F:/身份證號.txt"); BufferedReader in = new BufferedReader(new InputStreamReader(fis)); try { String s, s2 = new String(); while ((s = in.readLine()) != null) { s2 += s + "\n "; } in.close(); System.out.println(s2); } catch (IOException e) { System.out.println("學生信息文件讀取錯誤"); e.printStackTrace(); } }catch (FileNotFoundException e) { System.out.println("學生信息文件找不到"); e.printStackTrace(); } } }
運行:
代碼2:
package project7; //消極處理方式 import java.io.*; class ExceptionTest2 { public static void main (String args[]) throws IOException { FileInputStream fis=new FileInputStream("F:/身份證號.txt"); BufferedReader in = new BufferedReader(new InputStreamReader(fis)); String s, s2 = new String(); while ((s = in.readLine()) != null) { s2 += s + "\n "; } in.close(); System.out.println(s2); } }
運行:
實驗3: 編程練習
編寫一個計算器類,能夠完成加、減、乘、除的操做;
利用計算機類,設計一個小學生100之內數的四則運算練習程序,由計算機隨機產生10道加減乘除練習題,學生輸入答案,由程序檢查答案是否正確,每道題正確計10分,錯誤不計分,10道題測試結束後給出測試總分;
將程序中測試練習題及學生答題結果輸出到文件,文件名爲test.txt;
在以上程序適當位置加入異常捕獲代碼。
代碼:
package project7; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Scanner; public class jisuan { public static void main(String[] args) { Scanner in = new Scanner(System.in); jieguo student=new jieguo(); PrintWriter out = null; try { out = new PrintWriter("text.txt"); } catch (FileNotFoundException e) { e.printStackTrace(); } int sum = 0; for (int i = 1; i <=10; i++) { int a = (int) Math.round(Math.random() * 100); int b = (int) Math.round(Math.random() * 100); int c= (int) Math.round(Math.random() * 3); switch(c) { case 0: System.out.println(i+": "+a+"/"+b+"="); while(b==0) { b = (int) Math.round(Math.random() * 100); } int C = in.nextInt(); out.println(a+"/"+b+"="+C); if (C == student.division(a, b)) { sum += 10; System.out.println("right"); } else { System.out.println("false"); } break; case 1: System.out.println(i+": "+a+"*"+b+"="); int D = in.nextInt(); out.println(a+"*"+b+"="+D); if (D == student.multiplication(a, b)) { sum += 10; System.out.println("right"); } else { System.out.println("false"); } break; case 2: System.out.println(i+": "+a+"+"+b+"="); int E = in.nextInt(); out.println(a+"+"+b+"="+E); if (E == student.add(a, b)) { sum += 10; System.out.println("right"); } else { System.out.println("false"); } break ; case 3: System.out.println(i+": "+a+"-"+b+"="); int F = in.nextInt(); out.println(a+"-"+b+"="+F); if (F == student.reduce(a, b)) { sum += 10; System.out.println("right"); } else { System.out.println("false"); } break ; } } System.out.println("成績"+sum); out.println("成績:"+sum); out.close(); } }
package project7; public class jieguo { private int a; private int b; public int add(int a,int b) { return a+b; } public int reduce(int a,int b) { return a-b; } public int multiplication(int a,int b) { return a*b; } public int division(int a,int b) { if(b!=0) return a/b; else return 0; } }
運行:
實驗4:斷言、日誌、程序調試技巧驗證明驗。
實驗程序1:
//斷言程序示例 public class AssertDemo { public static void main(String[] args) { test1(-5); test2(-3); } private static void test1(int a){ assert a > 0; System.out.println(a); } private static void test2(int a){ assert a > 0 : "something goes wrong here, a cannot be less than 0"; System.out.println(a); } }
在elipse下調試程序AssertDemo,結合程序運行結果理解程序;
註釋語句test1(-5);後從新運行程序,結合程序運行結果理解程序;
掌握斷言的使用特色及用法。
運行:
註釋語句test1(-5);後從新運行程序,控制檯只輸出-3,不輸出-5
實驗程序2:
用JDK命令調試運行教材298頁-300頁程序7-2,結合程序運行結果理解程序;
並掌握Java日誌系統的用途及用法。
使用命令行調試。。。調試不出
實驗程序3:
用JDK命令調試運行教材298頁-300頁程序7-2,結合程序運行結果理解程序;
按課件66-77內容練習並掌握Elipse的經常使用調試技術。
代碼:
package logging; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.logging.*; import javax.swing.*; /** * A modification of the image viewer program that logs various events. * @version 1.03 2015-08-20 * @author Cay Horstmann */ public class LoggingImageViewer { public static void main(String[] args) { if (System.getProperty("java.util.logging.config.class") == null && System.getProperty("java.util.logging.config.file") == null) { try { Logger.getLogger("com.horstmann.corejava").setLevel(Level.ALL); //開啓全部級別的記錄 final int LOG_ROTATION_COUNT = 10; var handler = new FileHandler("%h/LoggingImageViewer.log", 0, LOG_ROTATION_COUNT); Logger.getLogger("com.horstmann.corejava").addHandler(handler); //增長這個日誌記錄器中的一個處理器 } catch (IOException e) { Logger.getLogger("com.horstmann.corejava").log(Level.SEVERE, "Can't create log file handler", e); } } //這段代碼確保將全部消息記錄到應用特定的文件中 EventQueue.invokeLater(() -> { var windowHandler = new WindowHandler();//經過Hander類自定義一個處理器 windowHandler.setLevel(Level.ALL); Logger.getLogger("com.horstmann.corejava").addHandler(windowHandler); var frame = new ImageViewerFrame(); frame.setTitle("LoggingImageViewer"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Logger.getLogger("com.horstmann.corejava").fine("Showing frame"); frame.setVisible(true); }); } } /** * The frame that shows the image. */ class ImageViewerFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 400; private JLabel label; private static Logger logger = Logger.getLogger("com.horstmann.corejava"); //調用Logger類的getLogger方法獲得一個日誌記錄器 public ImageViewerFrame() { logger.entering("ImageViewerFrame", "<init>"); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // set up menu bar var menuBar = new JMenuBar(); setJMenuBar(menuBar); var menu = new JMenu("File"); menuBar.add(menu); var openItem = new JMenuItem("Open"); menu.add(openItem); openItem.addActionListener(new FileOpenListener()); var exitItem = new JMenuItem("Exit"); menu.add(exitItem); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { logger.fine("Exiting."); System.exit(0); } }); // use a label to display the images label = new JLabel(); add(label); logger.exiting("ImageViewerFrame", "<init>"); } private class FileOpenListener implements ActionListener { public void actionPerformed(ActionEvent event) { logger.entering("ImageViewerFrame.FileOpenListener", "actionPerformed", event); // set up file chooser var chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); // accept all files ending with .gif chooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { return f.getName().toLowerCase().endsWith(".gif") || f.isDirectory(); } public String getDescription() { return "GIF Images"; } }); // show file chooser dialog int r = chooser.showOpenDialog(ImageViewerFrame.this); // if image file accepted, set it as icon of the label if (r == JFileChooser.APPROVE_OPTION) { String name = chooser.getSelectedFile().getPath(); logger.log(Level.FINE, "Reading file {0}", name); label.setIcon(new ImageIcon(name)); } else logger.fine("File open dialog canceled."); logger.exiting("ImageViewerFrame.FileOpenListener", "actionPerformed"); } } } /** * A handler for displaying log records in a window. */ class WindowHandler extends StreamHandler { //WindowHandler這個處理器擴展於StreamHander類,而且安裝了一個流。 //使用這種方法時,處理器會緩存記錄,而且只有在緩存滿的時候,纔將它們寫入流中。 private JFrame frame; public WindowHandler() { frame = new JFrame(); var output = new JTextArea(); output.setEditable(false); frame.setSize(200, 200); frame.add(new JScrollPane(output)); frame.setFocusableWindowState(false); frame.setVisible(true); setOutputStream(new OutputStream() { public void write(int b)//write方法將流顯示輸出到文本框中。 { } // not called public void write(byte[] b, int off, int len) { output.append(new String(b, off, len)); //append 新構造的文件處理器對象應該追加在一個已存在的日誌文件尾部,則爲TRUE } }); } public void publish(LogRecord record) //將日誌發送到目的地 { if (!frame.isVisible()) return; super.publish(record); flush();//覆蓋publish方法,以便在處理器得到每一個記錄以後刷新緩衝區。 } }
結果沒能調試運行出來。。。
實驗總結:
本週主要講了異常方面的知識,學習了異常的處理方法,感受本身學的沒有特別清楚,尤爲是日誌方面的知識,最後一個程序閱讀特別困難,都沒調試出來。。。還須要繼續學習。