王方第九周Java實驗總結html
項目java |
內容程序員 |
這個做業屬於哪一個課程編程 |
https://www.cnblogs.com/nwnu-daizh/小程序 |
這個做業的要求在哪裏數組 |
https://www.cnblogs.com/nwnu-daizh/p/11703678.html網絡 |
做業學習目標app |
1.掌握java異常處理技術;less 2.瞭解斷言的用法;dom 3.瞭解日誌的用途; 4.掌握程序基礎調試技巧。
|
第一部分 基礎知識
異常 日誌 斷言和調試
異常概念
——異常、異常類型、聲明拋出異常、異常抽出、異常捕獲
異常:程序執行過程當中所發生的異常事件,它中斷指令的正常執行。
Java的異常處理機制能夠控制程序從錯誤產生的位置轉移到可以進行錯誤處理的位置。
程序中常出現的錯誤和問題有:
—用戶輸入錯誤
—設備錯誤
— 物理限制
—代碼錯誤
異常分類:Java把程序運行時的錯誤分爲兩類
(1)非致命異常:經過某種修訂後程序還可以繼續運行(異常),如:文件不存在、無效的數組下標、空引用、網絡斷開、打印機脫機磁盤滿等。Java提供了一種獨特的異常處理機制處理這類錯誤。
(2)致命異常:程序遇到了很是嚴重的不正常 狀態,不能簡單恢復執行,是致命性錯誤。如:內存耗盡、系統內部錯誤等。這種錯誤程序自己沒法解決。
Java的異常類直接或間接的繼承於Throwable類。出內置異常類外,程序員可自定義異常類。Java的異常類可分爲兩大類:
——Error
Error類層次結構描述了Java運行時系統的內部錯誤和資源耗盡錯誤。應運程序不該該捕獲這類異常,也不會捕獲這種異常。
——Exception
Exception類是需重點掌握的異常類。Exception層次結構又分解爲兩個分支:一個分支派生與RuntimeException;另外一個分支包含其餘異常。
RuntimeException爲運行時異常類,通常是程序錯誤產生。
派生於RuntimeException的異常類包含下面幾種狀況:
——錯誤的類型轉換
——數組訪問越界
——訪問空指針
........
java將派生與Error類或RuntimeException類的全部異常稱爲未檢查異常,編譯器不容許對它們異常處理。
注意:若是出現RuntimeException異常,就必定是程序員的問題!
非運行時異常中程序自己沒有問題,但因爲某種狀況的變化,程序不能正常運行,致使異常出現。
除運行時異常外,其餘繼承自Exception類的異常類包括:
——試圖在文件後面讀取數據
——試圖打開一個錯誤格式的URL
.......
編譯器要求程序必須對這類異常進行處理,稱爲已檢查異常。
IOException:輸入輸出異常類
——IOException:申請I/O操做沒有正常完成。
——EOFException:在輸入操做正常結束前碰見了文件結束符。
——FileNotFoundException:在文件系統中,沒有找到由文件名字符串指定的文件。
Exception的其它子類
聲明拋出(已檢查)異常
聲明拋出異常 :若是一個方法可能會生成 一些異常方法,可是該方法並不確切的知道如何對這些異常事件進行處理,此時,這個方法就需聲明拋出這些異常。
一個方法不只須要告訴編譯器將要返回什麼值,還要告訴編譯器會發生什麼異常。
聲明拋出異常在方法聲明中用throws子句中來指明。例如:-public FileInputStream(String name)throws
FileNotFoundException
throws子句能夠同時指明多個異常,說明該方法將不對這些異常進行處理,而是聲明拋出它們。
——Public static void main (String arg[])throws IOExeption,IndexOutOfBoundsException
如下4種狀況須要方法用Throws子句聲明拋出異常。
——方法調用拋出已檢查異常的方法。
——程序運行過程當中可能發生異常,而且利用throw語句拋出一個已檢查異常對象。
——程序出現錯誤。例如a[-1]=0;
——java虛擬機和運行時庫出現的內部異常。
一個方法必須聲明該方法全部可能拋出的已檢查異常,二未檢查異常要麼不可控(Error),要麼應該避免發生(RuntimeException)。若是方法沒有聲明全部可能已發生的已檢查異常,編譯器會給出一個錯誤消息。
拋出異常:
當Java營運程序出現錯誤時,會根據錯誤類型產生一個異常對象,這個對象包含了異常的類型和錯誤出現時程序所處的狀態信息。把異常對象遞交給Java編譯器的過程稱爲拋出。
拋出異常要生成異常對象,異常對象可由某些類的實例生成,也可由JVM生成。
拋出對象經過throw語句來實現。
如何拋出異常
首先決定拋出異常類型。
代碼爲: throw new EOFException();
或者
EOFException e= new EOFException();
Throw e;
對於已存在的異常類,拋出該類的異常對象步驟爲:
——找到一個合適的異常類
——建立這個類的一個對象
——將這個對象拋出。
一個方法拋出異常後,它就不能反悔調用者了。
建立異常類
自定義異常類:定義一個派生於Exception的直接或間接子類。如派生一個於Exception的類。
自定義異常類應該包括兩個構造器:
——默認構造器:
——帶有詳細描述信息的構造器(超類Throwable的toString方法會打印出這些詳細信息,有利於代碼調試)
捕獲異常:
程序運行期間,異常發生時,Java運行系統從異常生成的代碼塊開始,尋找相應的異常處理代碼,並將異常交給該處理方法,這一過程叫作捕獲。
某個異常發生時,若程序沒有在任何地方進行該異常的捕獲,則程序就會終止執行,並在控制檯上輸出異常信息。
若要捕獲一個異常,須要在程序中設置一個try/catch/finally塊 :
——Try語句括住可能拋出異常的代碼段。
——catch語句指明要捕獲的異常類及相應的處理代碼。
——finally語句指明必須執行的程序塊。
捕獲異常代碼爲:
Try{
.......
}
Catch(Exception e){
......}
Finally{
......},
try子句
捕獲異常的第一步是try{...}子句選定捕獲異常的代碼範圍,由try所限定的代碼塊中的語句在執行過程當中可能會自動生成異常對象並拋出。
對於異常處理,能夠捕獲,也能夠只聲明拋出不作任何處理。
catch子句
Catch塊是對異常對象進行處理的代碼:
每一個try代碼能夠伴隨一個或多個catch語句,用於處理try代碼中所生成的各種異常事件:
catch語句只須要一個形式參數指明它所能捕獲的異常類對象,這個異常類必須是Throwable的子類,運行時系統經過參數值把拋出的異常對象傳遞給catch塊:
Catch塊可經過異常對象調用類throwable
所提供的方法。
——getMessage()用來獲得有關異常事件的信息:
——printStackTrance()用來跟蹤異常事件發生時執行堆棧的內容。
能夠在一個try塊中捕獲多個異常類型,每一異常類型須要單獨的catch子句。如如下代碼所示:
Try{拋出異常代碼}
catch(ExceptionTypel e1){
拋出exceptionType1時要執行的代碼}
catch(ExceptionType2 e2){
拋出exceptionType1時要執行的代碼}
catch(ExceptionTypel e3){
拋出exceptionType3時要執行的代碼}
catch語句的順序:
——捕獲異常的順序和不一樣catch語句的順序有關,當捕獲到一個異常時,剩下的catch一句就再也不進行匹配。
——所以,在安排catch語句的順序時,首先應該捕獲最特殊的異常,而後再準建通常化,也就是通常先安排子類,再安排父類。
再次拋出異常與異常鏈
——catch子句也能夠拋出一個平常,這樣作的目的時改變異常的類型。
Finally子句
捕獲異常的最後一步是經過finally語句爲異常處理提供一個統一的出口,時的控制流程在轉到程序其它部分之前,可以對程序狀態作同一的管理。
不論在try代碼塊中是否發生了異常事件,finally塊中的語句都會被執行。
Java異常捕獲處理代碼的通常形式是:
try{//括號內爲被監視程序塊}
catch(異常類1 e1){//括號內爲處理異常類1的程序塊}
catch(異常類2 e2){//括號內爲處理異常類2的程序塊}
... ...
catch(異常類n en){//括號內爲處理異常類n的程序塊}
finally{//括號內必需要執行的程序塊}
異常處理中分析堆棧跟蹤元素
堆棧跟蹤是程序執行中一個方法調用過程的列表,它包含了程序執行過程當中方法調用的特定位置。
程序編碼時異常處理的兩種方式
(1) 積極處理方式
確切知道如何處理的異常應該捕獲;
(2) 消極處理方式
不知道如何去處理的異常聲明拋出。
異常處理的原則(*)
(1)異常處理不能代替簡單的條件檢測,旨在異常狀況下使用異常機制。例如:重複對空棧進行退棧操做。
(2)程序代碼不要很過度細化異常,儘可能將有可能產生異常的語句放在同一個try語句塊中。
(3)拋出的異常類型儘量明確。
(4)不要壓制異常,對於不多發生的異常,應該將其關閉。
(5)早拋出,晚捕獲,儘量讓高層次的方法通告用戶發生了錯誤。
斷言
斷言:是程序的開發和測試階段用於插入一些代碼檢測一些錯誤語句的工具。
斷言(assert)語法以下:
一、assert 條件或者二、assert 條件:表達式
編寫代碼時,咱們老是會作出一些假設,斷言就是用於在代碼中捕捉這些假設。斷言表示爲一些布爾表達式,程序員相信在程序中的某個特定點該表達式值爲真,能夠在任什麼時候候啓用和禁用斷言驗證,所以能夠在測試時啓用斷言而在部署時禁用斷言。一樣,程序投入運行後,最終用戶在遇到問題時能夠從新啓用斷言。
使用斷言能夠建立更穩定、品質更好且 不易於出錯的代碼。當須要在一個值爲FALSE時中斷當前操做的話,可使用斷言。單元測試必須使用斷言(Junit/JunitX)。
除了類型檢查和單元測試外,斷言還提供了一種肯定各類特性是否在程序中獲得維護的極好的方法。
斷言的使用
1.能夠在預計正常狀況下程序不會到達的地方放置斷言 :assert false
2.斷言能夠用於檢查傳遞給私有方法的參數。(對於公有方法,由於是提供給外部的接口,因此必須在方法中有相應的參數檢驗才能保證代碼的健壯性)
3.使用斷言測試方法執行的前置條件和後置條件
4.使用斷言檢查類的不變狀態,確保任何狀況下,某個變量的狀態必須知足。(如age屬性應大於0小於某個合適值)
斷言使用示例:
斷言在默認狀況下是關閉的,要在編譯時啓用斷言,須要使用source1.4標記 既javac source1.4 Test.java ,在運行時啓用斷言須要使用 -ea參數 。要在系統類中啓用和禁用斷言可使用 -esa 和 -dsa參數。
例如:
public class AssertExampleOne{
public AssertExampleOne(){}
public static void main(String args[]){
int x=10;
System.out.println("Testing Assertion that x==100");
assert x==100:"Out assertion failed!";
System.out.println("Test passed!");
}
}
若是編譯時未加 -source1.4,則編譯通不過
在執行時未加 -ea 時輸出爲
Testing Assertion that x==100
Test passed
jre忽略了斷言的舊代碼,而使用了該參數就會輸出爲
Testing Assertion that x==100
Exception in thread "main" java.lang.AssertionError: Out assertion failed!
at AssertExampleOne.main(AssertExampleOne.java:6)
JAVA程序中的調試技術
(1)應用局部Boolean變量
(2)應用全局Boolean變量
(3)使用斷言
Eclipse下程序調試:能夠交互式執行代碼,檢查變量和表達式的功能反應其強大性有效工具,同時 可檢查和修復JAVA程序代碼問題。
(1)條件斷點
(2)變量斷點
(3)方法斷點
(4)異常斷點
(5)從新調試
(6)單步執行程序
(7)檢查變量
(8)改變變量值
第二部分 實驗部分
1、實驗目的與要求
(1) 掌握java異常處理技術;
(2) 瞭解斷言的用法;
(3) 瞭解日誌的用途;
(4) 掌握程序基礎調試技巧;
2、實驗內容和步驟
實驗1:用命令行與IDE兩種環境下編輯調試運行源程序ExceptionDemo1、ExceptionDemo2,結合程序運行結果理解程序,掌握未檢查異常和已檢查異常的區別。
//異常示例1 public class ExceptionDemo1 { public static void main(String args[]) { int a = 0; System.out.println(5 / a); } }
//異常示例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(); } }
輸出結果截圖分別爲;
命令行輸出結果爲:
經過異常檢測後爲:
public class ExceptionDemo1 { public static void main(String[] args) { int a = 0; if(a==0) { System.out.println("除數爲零"); } else { System.out.println(5 / a); } } }
import java.io.*; public class ExceptionDemo2{ public static void main(String args[]) { FileInputStream fis; try { fis = new FileInputStream("text.txt"); int b; while((b=fis.read())!=-1) { System.out.print(b); } fis.close(); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace();//打印堆棧信息 // System.out.println("Hello."); }//JVM自動生成異常對象 } }
輸出結果截圖爲:
實驗2: 導入如下示例程序,測試程序並進行代碼註釋。
測試程序1:
l 在elipse IDE中編輯、編譯、調試運行教材281頁7-1,結合程序運行結果理解程序;
l 在程序中相關代碼處添加新知識的註釋;
掌握Throwable類的堆棧跟蹤方法;
程序7-1的源代碼爲:
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 + "):"); var walker = StackWalker.getInstance();//建立一個新的StackWalker walker.forEach(System.out::println); 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) { try (var in = new Scanner(System.in)) //新建立一個輸入的Scanner 對象,而後賦值給in { System.out.print("Enter n: "); int n = in.nextInt(); factorial(n); } } }
程序運行結果截圖爲:
測試程序2:
l Java語言的異常處理有積極處理方法和消極處理兩種方式;
l 下列兩個簡單程序範例給出了兩種異常處理的代碼格式。在elipse IDE中編輯、調試運行源程序ExceptionTest.java,將程序中的text文件更換爲身份證號.txt,要求將文件內容讀入內容,並在控制檯顯示;
l 掌握兩種異常處理技術的特色。
//積極處理方式 import java.io.*; class ExceptionTest { public static void main (string args[]) { try{ FileInputStream fis=new FileInputStream("text.txt"); } catch(FileNotFoundExcption e) { …… } …… } }
//消極處理方式 import java.io.*; class ExceptionTest { public static void main (string args[]) throws FileNotFoundExcption { FileInputStream fis=new FileInputStream("text.txt"); } }
積極處理程序源代碼爲:
//積極處理方式 import java.io.*; import java.io.BufferedReader; import java.io.FileReader; class ExceptionTest { public static void main (String args[]) { File fis=new File("身份證號.txt"); try { FileReader fr = new FileReader(fis); BufferedReader br = new BufferedReader(fr); try { String s, s2 = new String(); while ((s = br.readLine()) != null) { s2 += s + "\n "; } br.close(); System.out.println(s2); }catch (IOException e) { e.printStackTrace(); } }catch(FileNotFoundExcption e) { e.printStackTrace(); } } }
消極處理程序代碼爲:
//消極處理方式 import java.io.*; class ExceptionTest1 { public static void main (String args[]) throws IOException { File fis=new File("身份證號.txt"); FileReader fr = new FileReader(fis); BufferedReader br = new BufferedReader(fr); String s, s2 = new String(); while ((s = br.readLine()) != null) { s2 += s + "\n "; } br.close(); System.out.println(s2); } }
輸出結果截圖爲:
實驗3: 編程練習
l 編寫一個計算器類,能夠完成加、減、乘、除的操做;
l 利用計算機類,設計一個小學生100之內數的四則運算練習程序,由計算機隨機產生10道加減乘除練習題,學生輸入答案,由程序檢查答案是否正確,每道題正確計10分,錯誤不計分,10道題測試結束後給出測試總分;
l 將程序中測試練習題及學生答題結果輸出到文件,文件名爲test.txt;
在以上程序適當位置加入異常捕獲代碼。
程序源代碼爲:
package test;
import java.util.Random;
import java.util.Scanner;
public class test{
int sum;
public static void main(String[] args) {
test t=new test();
System.out.println("本次測試共十道題,每題十分,滿分一百分");
t.sum=0;
Random r=new Random();
for(int i=0;i<10;i++) {
t.core();
}
System.out.println("考試結束");
System.out.println("你的總分爲"+t.sum);
}
private void core() {
Random r=new Random();
int m,n;
m=r.nextInt(11);
n=m%4;
switch(n) {
case 0:
int a ,b,c;
a=r.nextInt(101);
b=r.nextInt(101);
System.out.println(a+"+"+"("+b+")"+"=");
Scanner x=new Scanner(System.in);
c=x.nextInt();
if(c!=a+b)
System.out.println("回答錯誤");
else {
System.out.println("回答正確");
sum=sum+10;
}
break;
case 1:
int h,g,f;
h=r.nextInt(101);
g=r.nextInt(101);
System.out.println(h+"-"+"("+g+")"+"= ");
Scanner u=new Scanner(System.in);
f=u.nextInt();
if(f!=h-g)
System.out.println("回答錯誤");
else {
System.out.println("回答正確");
sum=sum+10;
}
break;
case 2:
int q,w,e;
q=r.nextInt(101);
w=r.nextInt(101);
System.out.println(q+"*"+"("+w+")"+"= ");
Scanner y=new Scanner(System.in);
e=y.nextInt();
if(e!=q*w)
System.out.println("回答錯誤");
else {
System.out.println("回答正確");
sum=sum+10;
}
break;
case 3:
double j,k,l;
j=r.nextInt(101);
k=r.nextInt(101);
if(k==0)
k++;
System.out.println(j+"/"+"("+k+")"+"= ");
Scanner z=new Scanner(System.in);
l=z.nextDouble();
if(l!=(j/k)/1.00)
System.out.println("回答錯誤");
else {
System.out.println("回答正常");
sum=sum+10;
}
break;
}
}
}
輸出結果截圖爲:
實驗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); } }
l 在elipse下調試程序AssertDemo,結合程序運行結果理解程序;
l 註釋語句test1(-5);後從新運行程序,結合程序運行結果理解程序;
l 掌握斷言的使用特色及用法。
輸出結果截圖爲:
註釋過(-5)後
實驗程序2:
l 用JDK命令調試運行教材298頁-300頁程序7-2,結合程序運行結果理解程序;
並掌握Java日誌系統的用途及用法。
程序代碼爲:
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; Handler 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(() -> { Handler windowHandler = new WindowHandler(); windowHandler.setLevel(Level.ALL); Logger.getLogger("com.horstmann.corejava").addHandler(windowHandler); JFrame 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"); public ImageViewerFrame() { logger.entering("ImageViewerFrame", "<init>"); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // set up menu bar JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu menu = new JMenu("File"); menuBar.add(menu); JMenuItem openItem = new JMenuItem("Open"); menu.add(openItem); openItem.addActionListener(new FileOpenListener()); JMenuItem 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 JFileChooser 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 { private JFrame frame; public WindowHandler() { frame = new JFrame(); final JTextArea 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) { } // not called public void write(byte[] b, int off, int len) { output.append(new String(b, off, len)); } }); } public void publish(LogRecord record) { if (!frame.isVisible()) return; super.publish(record); flush(); } }
程序運行結果爲:
實驗程序3:
l 用JDK命令調試運行教材298頁-300頁程序7-2,結合程序運行結果理解程序;
l 按課件66-77內容練習並掌握Elipse的經常使用調試技術。
l 畫ULML圖(思惟導圖)四則混合運算(運算出錯)小程序軟件
第三部分 實驗總結
(1)在上週的學習過程當中咱們主要學習了異常、日製、斷言和調試的相關概念及知識。經過學習異常咱們更加深刻的理解了在平時的學習過程當中出現的錯誤,好比文件的輸入等。同時我也意識到有些錯誤是咱們能夠經過調試,修改代碼等來改變的。而有些錯誤是咱們不能人爲控制的,好比電腦內存不夠等問題。捕獲異常也是咱們應當尤其重視的知識,想要改正錯誤,咱們首先得找到錯誤來源,而後進行處理。(2)經過上次的考試,我意識到本身還有不少不足,編寫程序是個人短板到同時理論知識我也沒有足夠的掌握,致使成績很不理想,但願之後能夠繼續努力。