201871010112-梁麗珍《面向對象程序設計(java)》第十週學習總結

 

項目php

內容html

這個做業屬於哪一個課程java

https://www.cnblogs.com/nwnu-daizh/程序員

這個做業的要求在哪裏typescript

https://www.cnblogs.com/nwnu-daizh/p/11778090.html數據庫

做業學習目標編程

                        1.掌握java異常處理技術;數組

                        2.瞭解斷言的用法;緩存

                        3.瞭解日誌的用途;安全

                        4.掌握程序基礎調試技巧。

第一部分:總結第七章關於異常處理相關理論知識

  1. 概述:異常就是java程序在運行過程當中出現的錯誤。
  2. 異常發生時如何處理,java提供瞭解決辦法:異常處理機制。
  3. java中的異常能夠是函數中的語句執行時引起的,也能夠是程序員經過throw語句手動拋出。
  4. 只要在java程序中產生了異常,就會用一個對應類型的異常對象來封裝異常,JRE會試圖尋找異常處理程序來處理異常。
  5. JDK中內建類一些常見的異常類,咱們也能夠自定義異常。
  6. Throwable類是java異常類型的頂層父類,一個對象只有是Throwable類的直接或間接實例,他纔是一個異常對象,才能被異常處理機制識別。

異常分類

一、檢查性異常:

(1)最具表明性的檢查性異常是用戶錯誤或問題引發的異常,這是程序員沒法預測的。
(2)例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單的忽略。

二、運行時異常:

(1)運行時異常是可能被程序員避免的異常。
(2)與檢查性異常相反,運行時異常能夠在編譯時被忽略。

三、錯誤:

(1)錯誤不是異常,而是脫離程序員控制的問題。
(2)錯誤在代碼中一般被忽略。
(3)例如,當棧溢出時,一個錯誤就發生了,它們在編譯時也是檢查不到的。

四、異常分類圖解:

 

 

Error和Exception類

  1. java標準庫內建了一些通用的異常,這些類以Throwable爲頂層父類。
  2. Throwable又派生出Error類和Exception類。
  3. Error類:

    1)Error類以及他的子類的實例,表明了JVM自己的錯誤。 (2)錯誤不能被程序員經過代碼處理,Error不多出現。 (3)所以,程序員應該關注Exception爲父類的分支下的各類異常類
  4. Exception類:

     
    1)Exception及他的子類,表明程序運行時發送的各類不指望發生的事件。 (2)能夠被java異常處理機制使用,是異常處理的核心。
  5. Error錯誤是沒法恢復,不能獲取的,如系統崩潰,虛擬機錯誤,動態連接失敗等。這會致使程序直接中斷。
  6. Exception是咱們常說的異常,他又大體分爲兩類,一類是運行時異常:RuntimeException,另外一類就是其餘異常。由於RuntimeException是由Java虛擬機自動拋出並自動捕獲,因此又叫非檢查異常。而另外一類異常就不同了,須要咱們手動的捕獲和處理異常,因此叫作檢查異常

異常處理

  1. 異常處理機制能讓程序在發生異常時,按照代碼預先設定的異常處理邏輯,針對性的處理異常,讓程序盡最大可能的恢復正常並繼續執行,且保持代碼的清晰。
  2. java中,異常處理的任務就是將執行控制流從異常發生的地方轉移到可以處理這種異常的地方去。
  3. java異常處理涉及到五個關鍵字,分別是:try、catch、finally、throw、throws。
    1. try    -- 用於監聽。將要被監聽的代碼(可能拋出異常的代碼)放在try語句塊以內,當try語句塊內發生異常時,異常就被拋出。
    2. catch  -- 用於捕獲異常。catch用來捕獲try語句塊中發生的異常。在編寫多個catch的時候,捕獲範圍大的異常必定要放在捕獲範圍小的異常後面。
    3. finally -- finally語句塊老是會被執行。它主要用於回收在try塊裏打開的物力資源(如數據庫鏈接、網絡鏈接和磁盤文件)。只有finally塊執行完成以後,纔會回來執行try或者catch塊中的return或者throw語句,若是finally中使用了return或者throw等終止方法的語句,則就不會跳回執行,直接中止。
    4. throw  -- 用於拋出一個實例化的異常對象。
    5. throws -- 用在方法簽名中,用於聲明該方法可能拋出的異常,若是方法真的出現異樣,將交由調用者來處理。調用了具備throws申明的方法以後,無論異常是否出現,調用者必須使用try...catch處理。調用聲明瞭運行時異常的函數,能夠不強制處理,將交給jvm默認處理。
  4. 在編寫代碼處理異常時,對於檢查異常,有兩種處理方式:

     
    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...catch

        

 

  若是try塊裏的業務邏輯代碼出現了異常,系統就會生成一個異常對象,而後將該對象提交給Java運行時環境(throw),接着查找catch塊,若是找到了合適的catch塊,就將該異常對象交由該catch塊處理。這個過程又叫作捕獲(catch)異常;若是找不到合適的catch塊,程序將退出。

 

finally回收資源

  finally,最終的,也就是咱們處理完異常最後要作的事情。因爲有時候咱們會在try塊裏面使用一些資源,這些資源最後也就在finally塊裏被回收掉了。

    

異常鏈

  對於一個完整的應用而言,都是有比較嚴格的分層關係的,上層依賴下層的API。而對於用戶而言,咱們不想看到底層的SQL異常,同時也會使得系統不安全。因此這時咱們就要將底層的異常捕獲,而後再拋出一個新的業務異常,就能夠在新的異常中給出用戶比較友好的提示信息。               

或者咱們也能夠這樣處理異常:

 這是因爲Throwable基類有了一個能夠接受Exception參數的方法。

自定義異常

雖然java已經提供了不少系統性異常,但在開發中仍是沒法知足實際的須要。因此java容許用戶自定義異常。語法以下:

    

總結

  1. 處理運行時異常時,採用邏輯去合理規避,同時輔助使用try-catch處理。
  2. 在多重catch塊後面,加一個catch(Exception)來處理可能遺漏的異常。
  3. 對於不肯定的代碼,也能夠加上try-catch,處理潛在的異常。
  4. 儘可能去處理異常,切記只是簡單的調用printStackTrace()去打印輸出。
  5. 儘可能添加finally塊去釋放所佔用的資源。
  6. 具體若是處理異常,要根據不一樣的業務需求和異常類型去決定。

2、實驗內容和步驟

實驗1:用命令行與IDE兩種環境下編輯調試運行源程序ExceptionDemo1ExceptionDemo2,結合程序運行結果理解程序,掌握未檢查異常和已檢查異常的區別。

示例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中編輯、編譯、調試運行教材2817-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方法,以便在處理器得到每一個記錄以後刷新緩衝區。
   }
}

結果沒能調試運行出來。。。

 

實驗總結:

  本週主要講了異常方面的知識,學習了異常的處理方法,感受本身學的沒有特別清楚,尤爲是日誌方面的知識,最後一個程序閱讀特別困難,都沒調試出來。。。還須要繼續學習。

相關文章
相關標籤/搜索