Java(十三)

知识点1:异常的理解

在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等等。

//InputMismatchException:输入不匹配的异常
    public static void main(String[] args) {
        System.out.println("请输入一个整型数据:");
        Scanner scanner = new Scanner(System.in);
        int number = scanner.nextInt();
        System.out.println(number);

        scanner.close();
    }

知识点2:异常的体系结构

1. 体系结构

 * 一、异常的体系结构
 * java.lang.Throwable
 *      |----java.lang.Error:错误。一般不编写针对性的代码进行处理。
 *      |----java.lang.Exception:异常。可以使用针对性的代码进行处理。
 *            |-----编译时异常:编译过程中可能出现的异常类型
 *            |-----运行时异常(RuntimeException):编译过程(javac.exe)可以正常通过,运行时报出的异常。
 *

2. 关于Error的理解

/**
 * @author shkstart
 * @create 2020-08-08 10:16
 *
 * Error:一般不编写针对性的代码进行处理。
 */
public class ErrorTest {
    public static void main(String[] args) {
//        main(args);//StackOverflowError:栈溢出的错误
        //OutOfMemoryError: Java heap space:堆空间溢出的错误
        byte[] arr = new byte[1024 * 1024 * 1024];//1GB
    }
}

知识点3:常见的异常类型及举例(掌握)

1. 运行时异常

//InputMismatchException:输入不匹配的异常
    public static void main(String[] args) {
        System.out.println("请输入一个整型数据:");
        Scanner scanner = new Scanner(System.in);
        int number = scanner.nextInt();
        System.out.println(number);

        scanner.close();
    }

    //ArrayIndexOutOfBoundsException
    @Test
    public void test1(){
        int[] arr = new int[10];
        System.out.println(arr[10]);
        System.out.println("hello");
    }

    //NullPointerException
    @Test
    public void test2(){
//        Date date = new Date();
//        date = null;
//        System.out.println(date.toString());

        String str = null;
        System.out.println(str.toString());
    }

    //ArithmeticException:算术异常
    @Test
    public void test3(){
        int m = 10;
        int n = 0;
        System.out.println( m / n);
    }

    //ClassCastException
    @Test
    public void test4(){
        Object obj = new Date();
        String str = (String) obj;
    }

    //NumberFormatException:数值格式化的异常
    @Test
    public void test5(){
        String str = "123a";
        int num = Integer.parseInt(str);
        System.out.println(num);


    }

2. 编译时异常

//FileNotFoundException
    //IOException
    @Test
    public void test6(){
//        File file = new File("hello.txt");
//        FileInputStream fis = new FileInputStream(file);
//        int data = fis.read();
//        while(data != -1){
//            System.out.print((char)data);
//            data = fis.read();
//        }
//
//        fis.close();
    }

//ClassNotFoundException
    @Test
    public void test7(){
        Class clazz = Class.forName("java.lang.String");
        
    }

知识点4:异常处理的方式1:try-catch-finally

1. 理解

 /* 一、java程序的异常处理:抓抛模型
 *
 * 过程一:抛 (生成异常对象、并抛出)
 *      java程序在执行过程中,一旦出现异常,就会在异常出现的位置生成一个相应异常类型的对象。
 *      并将此对象抛出。
 *      > 一旦程序出现异常,就不再执行异常之后的代码了。
 *
 *      > 生成异常对象有两种方式:① 系统自动生成  ② 使用throw + 异常对象
 *
 * 过程二:抓 (异常处理的过程)
 *      可以理解为异常处理的方式。
 *      异常处理有两种方式:
 *              > 方式一:try-catch-finally
 *              > 方式二:throws
 */

2. try-catch

 /*二、try-catch-finally的使用

 * try{
 *      可能存在异常的代码
 * }catch(异常类型1 变量名1){
 *      异常的处理方式1
 * }catch(异常类型2 变量名2){
 *      异常的处理方式2
 * }...
 * finally{
 *      一定会被执行的代码
 * }
 *
 * 说明:
 * 1. finally是可选的。
 * 2. 将可能存在异常的代码声明在try中。一旦执行过程中出现异常,此异常对象就会抛出。进而匹配之后的catch结构
 * 一旦与某一个catch结构匹配,进入catch的大括号中执行异常处理的代码。一旦执行完此catch结构,不再执行其后
 * 的其他catch结构。
 * 3. 一旦程序通过try-catch的方式处理了异常,则程序让可以继续向下执行。
 * 4. 如果声明了多个catch,多个catch对应异常类型不存在子父类关系的话,则哪个类型声明在上面,哪个
 * 类型声明在下面都可以。
 * 如果多个catch对应异常类型满足子父类的关系,则必须将子类类型声明在父类类型的上面。
 * 5. 在try中声明的变量,在出了try结构以后就失效了。
 * 6. catch中常见的异常处理的方式:
 * ① 通过打印,指名异常的类型信息
 * ② getMessage()
 * ③ printStackTrace()  (推荐)
 * 7. try-catch-finally结构是可以嵌套使用的
 */
  • 代码演示
public class TryCatchFinallyTest {

    @Test
    public void test1() {
        int[] arr = null;
        try {
            arr = new int[10];
            System.out.println(arr[10]);//创建了一个ArrayIndexOutOfBoundsException类型的对象。
            System.out.println("hello1");
        } catch (NullPointerException e) {
            System.out.println("出现空指针的异常了....");
        } catch (ArrayIndexOutOfBoundsException e) {
//            System.out.println("出现角标越界的异常了....");
//            System.out.println(e.getMessage());
            e.printStackTrace();
        } catch (RuntimeException e) {
            System.out.println("出现了运行时的异常了....");
        }

        System.out.println("hello2");
        System.out.println(arr[1]);
    }

    @Test
    public void test2() {
        try {
            Object obj = new Date();
            String str = (String) obj;

        } catch (ClassCastException e) {
            e.printStackTrace();
        }
        System.out.println("hello");
    }

    //###############针对于编译时异常来说########################
    @Test
    public void test3() {

        try {
            File file = new File("hello1.txt");
            FileInputStream fis = new FileInputStream(file);
            int data = fis.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fis.read();
            }

            fis.close();
        }catch(FileNotFoundException e){
//            System.out.println("出现文件找不到的异常了....");
            e.printStackTrace();
        }catch(IOException e){
//            System.out.println("出现了IO的异常了...");
            e.printStackTrace();
        }
    }

    @Test
    public void test4(){
        try{
            Class clazz = Class.forName("java.lang.String");

            //。。。。

        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}

3.结论

 /* 1. 针对于编译时异常,我们必须要进行异常的处理,否则编译不通过。
 *    我们针对编译时异常进行处理以后,相当于将一个编译时异常转变为在运行时才可能出现的异常。
 *
 * 2. 针对于运行时异常,其实我们可以不使用异常处理。
 */

4. finally的使用

package com.atguigu.java;

import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

/**
 * @author shkstart
 * @create 2020-08-08 14:15
 *
 *
 * finally的使用
 *
 * 1. finally是可选的。
 * 2.将一定会被执行的代码声明在finally中。
 *    即使try、catch中存在未被处理的异常,或try、catch有return返回值结构,我们说,finally也是一定要被执行的。
 *
 * 3. 开发中哪些代码会放在finally中?
 *   IO流、Socket、数据库连接等资源,都需要手动的关闭。那么需要保证此关闭操作一定要被执行。否则,会
 *   出现内存泄漏。
 *
 *
 *   面试题:final \ finally \ finalize的区别
 *
 */
public class FinallyTest {
    @Test
    public void test1(){
        try{
            int[] arr = new int[10];
            System.out.println(arr[10]);

            int m = 10;
            int n = 0;
            System.out.println( m / n);
        }catch(ArithmeticException e){
            e.printStackTrace();

//            int[] arr = new int[10];
//            System.out.println(arr[10]);
        }finally{
            System.out.println("hello----1");
        }


        System.out.println("hello----2");
    }


    public int method1(){
        try{
            int m = 10;
            int n = 0;
            System.out.println( m / n);
            return 1;
        }catch(ArithmeticException e){
            return 2;
        }finally{
            return 3;
        }
    }

    @Test
    public void test2(){
        int num = method1();
        System.out.println(num);
    }

    @Test
    public void test3(){
        FileInputStream fis = null;
        try {
            File file = new File("hello.txt");
            fis = new FileInputStream(file);

            int data = fis.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fis.read();
            }


        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            //必须手动关闭资源
            try {
                if(fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    public void test4(){
        Scanner scanner = null;
        try{
            System.out.println("请输入一个整型数据:");
            scanner = new Scanner(System.in);
            int number = scanner.nextInt();
            System.out.println(number);

        }finally{
            if(scanner != null)
                scanner.close();

        }
    }
}

知识点5:异常处理的方式2:throws + 异常类型

1. 使用

 /* 1. 异常处理的方式二:在方法的声明处,使用:throws + 异常类型
 *     > 在方法内,执行过程中,一旦出现异常,就会生成一个指定异常类型的对象。使用“throws + 异常类型”
 *     方式处理异常的话,就会将此异常对象抛给方法的调用者。 方法的调用者需要继续考虑如何处理异常?
 *     比如:method1()中出现的异常,method1选择了“throws + 异常类型”的方式处理,则将异常抛给了其调用
 *     者:method2()
 */
  • 代码演示
public class ThrowsTest {

    public static void main(String[] args) {
        ThrowsTest test = new ThrowsTest();
        test.method3();
    }

    public void method3(){
        try{
            method2();

        }catch(Exception e){
            e.printStackTrace();
//            System.out.println("出现异常了");
        }
        System.out.println("hello");
    }

    public void method2() throws Exception {
        method1();
    }


    public void method1() throws FileNotFoundException , IOException {
        File file = new File("hello.txt");
        FileInputStream fis = new FileInputStream(file);
        int data = fis.read();
        while(data != -1){
            System.out.print((char)data);
            data = fis.read();
        }

        fis.close();
    }
}

2. try-catch-finally与throws的选择

/*在开发中,如何选择异常处理的方式?
 *
 *     ① 如果程序中涉及到一定要被执行的代码(比如:流、Socket、数据库连接等),我们需要选择
 *     try-catch-finally方式处理异常。
 *
 *     ② 如果父类被重写的方法声明时,没有使用throws的方式抛出异常。则子类重写的方法内部如果有异常,
 *     只能使用try-catch-finally的方式处理,不能使用throws的方式了。
 *
 *     ③ 如果一个方法method1()内,先后调用了另外了几个方法。比如:method2(),method3(),method4().
 *     此时method2(),method3(),method4()是递进关系的调用。此时,method2(),method3(),method4()
 *     中,我们选择使用throws的方式处理异常。而在method1()中统一的使用try-catch-finally的方式处理异常。
 */

知识点6:使用throw+异常对象,手动抛出

/**
 * @author shkstart
 * @create 2020-08-08 15:40
 *
 * throw的使用:
 *  在方法内部,可以手动的生成一个异常类的对象,并将此对象抛出。使用“throw + 异常对象”
 *
 *
 */
public class ThrowTest {
    public static void main(String[] args) {
        try {
            Student s1 = new Student();
            s1.regist(-1001);

            System.out.println(s1);
        }catch(Exception e){
//            e.printStackTrace();
            System.out.println(e.getMessage());

        }


    }
}

class Student{
    private int id;

    public void regist(int id) throws Exception{
        if(id > 0){
            this.id = id;
        }else{
//            throw new RuntimeException("输入的学号不能为0或负数");
//            throw new Exception("输入的学号不能为0或负数");

            //编译不通过
//            throw new String("输入的学号不能为0或负数");

            throw new MyException("输入的学号不能为0或负数");
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                '}';
    }
}
  • throw与throws的对比
 /* 面试题:throw 和 throws 的区别
 *
 *  throw:在生成异常对象并抛出的环节使用。表示手动抛出一个new的异常对象。
 *         写在方法内部
 *  throws:是针对于生成异常对象并抛出之后,考虑如何处理异常的一种方式。
 *         写在方法的声明处。
 */

知识点7:自定义异常类型

/**
 * @author shkstart
 * @create 2020-08-08 15:51
 *
 * 自定义异常类
 * 1. 需要继承于现有的异常体系结构。比如:继承于RuntimeException 、 Exception
 * 2. 需要提供一个序列版本号:serialVersionUID
 * 3. 提供重载的构造器
 */
public class MyException extends Exception {
    static final long serialVersionUID = -338751694229948L;

    public MyException(String message) {
        super(message);
    }

    public MyException() {
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值