选择排序&二分查找&异常

11 篇文章 0 订阅
11 篇文章 0 订阅

选择排序&二分查找&异常

能够理解选择排序的执行原理
	选择排序:使用数组中的元素依次和其他的元素比较,把小的值往前放
能够理解二分查找的执行原理
	使用公式:mid = (min+max)/2;
	使用被查找的元素和中间索引指向的元素比较,循环执行的条件 min<=max
	1.被查找的元素>中间指针执向的元素 min = mid+1;
	2.被查找的元素<中间指针执向的元素 max = mid-1;
	3.被查找的元素==中间指针执向的元素 找到了,返回mid
能够辨别程序中异常和错误的区别
	错误:严重的问题,必须修改代码才能解决
	异常:可以解决的问题,使用try...catch解决异常之后,程序可以继续执行
说出异常的分类
	编译期异常==>Exception:写代码的时候会报的异常
	运行期()异常==>RuntimeException:运行代码的时候报的异常
列举出常见的三个运行期异常
	ClassCastException:类型转换异常(向下转型)
	NullPointerException:空指针异常
	IndexOutOfBoundsException:索引越界异常(集合会抛出)
	ArrayIndexOutOfBoundsException:数组索引越界异常
	StringIndexOutOfBoundsException:字符串索引越界异常
能够使用try...catch关键字处理异常(重点)  ctrl+alt+t
	try{
		可能产生异常的代码
		throw new xxxException("异常的信息");
		...
		throw new yyyException("异常的信息");
	}catch(xxxException e){ 
		异常的处理逻辑
	}
	...
	catch(yyyException e){
		异常的处理逻辑
	}
能够使用throws关键字处理异常(重点) alt+回车
	修饰符 返回值类型 方法名(参数) throws xxxException,...,yyyException{
		throw new xxxException("异常的信息");
		...
		throw new yyyException("异常的信息");
	}
能够自定义并使用异常类
	1.自定义异常的类名,一般都是以Exception结尾,说明这个类是一个异常相关的类(见名知意)
	2.自定义异常
		a.必须继承Exception:自定义的异常就是一个编译期异常
			使用:如果在方法内部抛出了编译期异常,那么我们就必须处理这个异常
				1.使用throws声明抛出异常,最终抛出给方法的调用者处理
				2.使用try...catch自己捕获处理异常
	    b.必须继承RuntimeException:z自定义的异常就是一个运行期异常
			使用:如果在方法内部抛出了运行期异常,我们无需处理,默认交给JVM处理(中断处理)

第一章 选择排序(重点)

1.原理

请添加图片描述

2.代码实现

package com.itheima.demo01sort;

import java.util.Arrays;

/*
    选择排序:使用中的元素依次和其他的元素进行比较,每次选出最小的值,把小的值往前放
 */
public class Demo01SelectSort {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {5,1,8,3};
        System.out.println("排序前数组中的元素:"+ Arrays.toString(arr));
        /*
            选择排序
                1.定义一个循环嵌套
                    外层循环:控制比较的次数 arr.length-1
                    内层循环:控制每次比较几对元素 int j = 1+i
                2.在循环中依次比较arr[i]和arr[j]的值,每次选出最小的
                    在if语句中使用第三方变量交互两个元素的位置
         */
        //1.定义一个循环嵌套
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 1+i; j < arr.length; j++) {
                //2.在循环中依次比较arr[i]和arr[j]的值,每次选出最小的
                if(arr[i]>arr[j]){
                    //在if语句中使用第三方变量交互两个元素的位置
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
            System.out.println("每次排序的结果:"+ Arrays.toString(arr));
        }
        System.out.println("排序后数组中的元素:"+ Arrays.toString(arr));
    }
}
排序前数组中的元素:[5, 1, 8, 3]
每次排序的结果:[1, 5, 8, 3]
每次排序的结果:[1, 3, 8, 5]
每次排序的结果:[1, 3, 5, 8]
排序后数组中的元素:[1, 3, 5, 8]

第二章 二分(折半)查找(重点)

1.原理

请添加图片描述

2.代码实现

package com.itheima.demo02search;

/*
    二分(折半)查找
    前提:
        数组|集合中的元素必须是有序的(升序)
 */
public class Demo01BinarySearch {
    public static void main(String[] args) {
        int[] arr = {-10,0,11,30,66,88};
        int i1 = binarySearch(arr, 66);
        System.out.println("i1:"+i1);//i1:4

        int i2 = binarySearch(arr, 100);
        System.out.println("i2:"+i2);//i2:-1

        int i3 = binarySearch(arr, -10);
        System.out.println("i3:"+i3);//i3:0
    }

    /*
        定义一个实现二分查找法的一个方法
        1.方法的参数传递要查找的数组和被查找的数组
        2.定义3个指针(min,mid,max)
        3.遍历数组,使用被查找的数和中间指针指向的元素比较,循环执行的条件(min<=max)
            被查找的元素>中间指针指向的元素 min = mid+1;
            被查找的元素<中间指针指向的元素 max = mid-1;
            被查找的元素==中间指针指向的元素 找到了,返回mid
        4.循环结束了,还没有找到,返回-1
     */
    //1.方法的参数传递要查找的数组和被查找的数组
    public static int binarySearch(int[] arr,int number){
        //2.定义3个指针(min,mid,max)
        int min = 0;//指向最小的元素
        int max = arr.length-1;//指向最大的元素
        int mid = 0;
        //3.遍历数组,使用被查找的数和中间指针指向的元素比较,循环执行的条件(min<=max)
        while (min<=max){
            //使用折半公式,计算mid的
            mid = (min+max)/2;
            if(number>arr[mid]){
                //被查找的元素>中间指针指向的元素 min = mid+1;
                min = mid+1;
            }else if(number<arr[mid]){
                //被查找的元素<中间指针指向的元素 max = mid-1;
                max = mid-1;
            }else{
                //被查找的元素==中间指针指向的元素 找到了,返回mid
                return mid;
            }
        }
        //4.循环结束了,还没有找到,返回-1
        return -1;
    }
}

第三章 异常

1.异常的概念

异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对

象。Java处理异常的方式是中断处理(停止java虚拟机JVM)。

2.异常的体系(重点)

请添加图片描述

package com.itheima.demo03Exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    异常和错误的区别(了解)
    java.lang.Throwable:是异常和错误的父类
        1.java.lang.Exception extends Throwable:异常(编译期异常),小问题,可以解决的,解决了异常之后,程序可以继续执行
            java.lang.RuntimeException extends Exception:运行期异常,程序运行期间出现的异常
        2.java.lang.Error extends Throwable:错误,严重的问题,不能解决
 */
public class Demo01Exception {
    public static void main(String[] args) {
        //编译期异常:写代码的时候(编译期,把.java文件编译生成.class文件),报的异常
        /*try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse("2021-1129");
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }*/

        //运行期异常,程序运行期间出现的异常
        /*try {
            int[] arr = {10,20,30};
            System.out.println(arr[3]);
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        /*
            错误,严重的问题,不能解决
            OutOfMemoryError: Java heap space 内存溢出的错误
            创建的数组太大了,超出了内存使用范围,(内存中装不下了),就会报内存溢出的错误
            必须的修改源码码,不让错误出现
         */
        //int[] arr = new int[1024*1000*1000];
        int[] arr = new int[1024*1000];

        System.out.println("后续代码");
        System.out.println("后续代码");
        System.out.println("后续代码");
        System.out.println("后续代码");
        System.out.println("后续代码");
        System.out.println("后续代码");
    }
}

3.异常的产生过程解析(面试)

package com.itheima.demo03Exception;

/*
    异常的产生过程解析
    分析异常是如何产生的,产生异常之后,JVM是如何处理异常的
 */
public class Demo02Exception {
    public static void main(String[] args) {
        int[] arr = {10,20,30};
        int ele = getElement(arr, 3);
        System.out.println(ele);
    }

    /*
        定义一个方法,获取数组指定索引处的元素返回
     */
    public static int getElement(int[] arr,int index){
        int e = arr[index];
        return e;
    }
}

请添加图片描述

4.throw关键字(重点)

throw:抛

作用:可以在方法中抛出指定的异常对象

package com.itheima.demo03Exception;

/*
    throw关键字(重点)
    作用:可以在方法中抛出指定的异常对象
    格式:
        修饰符 返回值类型 方法名(参数列表){
            throw new Exception("异常信息");
            throw new RuntimeException("异常信息");
            throw new xxxxException("异常信息");
        }
    注意:
        1.throw关键字必须写在方法中使用
        2.throw关键字后边创建的异常对象,必须使用Exception或者RuntimeException的子类对象,不能使用(Person,Student...)
        3.在方法中使用throw关键字抛出了编译异常,我们就必须处理这个编译异常
          在方法中使用throw关键字抛出了运行期异常,我们可以不用处理这个异常,最终交给JVM处理(中断)
 */
public class Demo03throw {
    public static void main(String[] args) {
        //int[] arr = {10,20,30};
        int[] arr = null;
        int ele = getElement(arr, 2);
        System.out.println(ele);
    }

    /*
        定义一个方法,获取数组指定索引处的元素返回
        在工作中:都会对方法传递进来的参数进行一些合法性的校验
        参数合法,程序正常执行
        参数不合法,以抛出异常的方法,告之方法调用者,传递的参数有问题
     */
    public static int getElement(int[] arr,int index){
        /*
            对方法的参数数组arr进行合法性校验,判断arr是否为null
            是null,使用throw关键字抛出空指针异常,告之方法的调用者"您传递的数组arr的值是null"
         */
        if(arr==null){
            throw new NullPointerException("您传递的数组arr的值是null");
        }
        /*
            对方法的参数数组索引index进行合法性校验,判断索引是否在数组索引的范围内
            不在索引范围内,使用throw关键字,抛出数组的索引越界异常,告之方法的调用者"您传递的数组的索引"+index+"不存在"
         */
        if(index<0 || index>arr.length-1){
            throw new ArrayIndexOutOfBoundsException("您传递的数组的索引"+index+"不存在");
        }
        int e = arr[index];
        return e;
    }
}

5.throws关键字(重点)

throws:抛出

异常处理的第一种方式:把产生的异常对象抛出给方法的调用者去处理

package com.itheima.demo03Exception;

/*
    throws关键字(重点)
        异常处理的第一种方式:把产生的异常对象抛出给方法的调用者去处理,建议练习的时候使用
     作用:
        方法的内部抛出了编译期异常对象,我们就必须的处理这个异常对象
        可以使用throws关键字来处理异常对象,把这个异常对象抛出给方法的调用者处理
        最终抛出给JVM处理,JVM会以红色的字体把异常对象相关信息打印的控制台,中断当前正在执行的程序
    弊端:
        产生异常的代码后边,还有其他的代码想执行,执行不到了,程序已经终止了
    格式:
        修饰符 返回值类型 方法名(参数列表) throws xxxException,...,yyyException{
            throw new xxxException("异常的信息");
            ...
            throw new yyyException("异常的信息");
        }
    注意:
        1.throws关键字必须写在方法声明处
        2.一般在方法内部抛出了什么异常对象,就使用throws关键字在方法上声明抛出什么异常对象
            a.在方法内部抛出了多个异常对象,就需要使用throws关键字在方法上声明多个异常对象
            b.在方法内部抛出的多个异常对象,如果有子父类关系,在方法上声明父类异常即可
        3.调用一个使用throws关键字声明异常的方法,那么我们就必须处理这个异常对象
            a.可以使用throws关键字继续声明抛出这个异常对象,最终会抛出给JVM处理
            b.可以使用try...catch自己手动的处理异常
 */
public class Demo04throws {
    /*
        public static void main(String[] args) throws Exception
        main方法接收到了getElement方法抛出的异常对象,把对象再继续抛出给JVM来处理==>中断处理
     */
    public static void main(String[] args) throws Exception{
        int[] arr = {10,20,30};
        //int[] arr = null;
        int ele = getElement(arr, 3);
        System.out.println(ele);
        System.out.println("后续100行代码...");
    }

    /*
        定义一个方法,获取数组指定索引处的元素返回
        在工作中:都会对方法传递进来的参数进行一些合法性的校验
        参数合法,程序正常执行
        参数不合法,以抛出异常的方法,告之方法调用者,传递的参数有问题
        public static int getElement(int[] arr,int index)throws Exception
        使用throws关键字:把创建的异常对象声明抛出给方法的调用者main方法处理
     */
    public static int getElement(int[] arr,int index)throws Exception{
        if(arr==null){
            throw new Exception("您传递的数组arr的值是null");
        }
        if(index<0 || index>arr.length-1){
            throw new Exception("您传递的数组的索引"+index+"不存在");
        }
        int e = arr[index];
        return e;
    }
}

6.throws抛出子父类异常的处理(重点)

在方法内部抛出的多个异常对象,如果有子父类关系,在方法上声明父类异常即可

package com.itheima.demo03Exception;

import java.io.FileNotFoundException;
import java.io.IOException;

/*
    在方法内部抛出的多个异常对象,如果有子父类关系,在方法上声明父类异常即可
    public class FileNotFoundException extends IOException extends Exception
    FileNotFoundException:文件找不到异常
    IOException:读写异常
        public static void main(String[] args)throws FileNotFoundException,IOException
    FileNotFoundException和IOException是子父类异常,抛出父类异常即可
    简化为:
        public static void main(String[] args)throws IOException
        public static void main(String[] args)throws Exception
 */
public class Demo05throws {
    public static void main(String[] args)throws Exception {
        //readFile("d:\\abc.java");
        //readFile(null);
        readFile("c:\\a.txt");
        System.out.println("后续代码!");
    }

    /*
        定义一个方法,方法的参数传递一个文件的路径:  d:\\abc.java
        在方法中根据文件的路径读取文件
     */
    public static void readFile(String path)throws FileNotFoundException,IOException{
        //判断路径path是否为null,是null抛出IOException
        if(path==null){
            throw new IOException("您传递的路径是null");
        }
        //判断路径path是否为d:\\abc.java,不是抛出FileNotFoundException
        if(!"d:\\abc.java".equals(path)){
            throw new FileNotFoundException("您传递的路径不是d:\\abc.java");
        }
        //根据路径读取文件
        System.out.println("读取到了d:\\abc.java文件,文件中的内容是abc!");
    }
}

7.try…catch关键字(重点)

package com.itheima.demo03Exception;

import java.io.FileNotFoundException;
import java.io.IOException;

/*
    try...catch关键字(重点):异常处理的第二种方式,建议在工作中使用
    作用:
        方法内部抛出了指定的编译期异常对象,我们就需要处理这个异常对象
        调用的方法上声明抛出了异常对象,我们需要处理这个异常对象
        可以使用try...catch关键字捕获处理异常,自己定义异常的处理方式
    好处:
        处理了异常对象之后,后续如果有代码,可以继续执行
    格式:
        try{
            可能产生异常的代码(没有异常的代码)
        }catch(定义一个异常相关的变量){ 变量的作用就是用来接收产生的异常对象
            异常的处理逻辑(想怎么写就怎么写)
        }
        ...
        catch(定义一个异常相关的变量){
            异常的处理逻辑(想怎么写就怎么写)
        }
    注意:
        1.try中可能产生什么异常对象,catch中就要定义什么异常变量来接收这个异常对象
        2.如果try中产生了异常对象,就会执行catch中异常的处理逻辑,执行完catch中的代码,继续执行try...catch后边的代码
        3.如果try中没有产生异常对象,就不会执行catch中异常的处理逻辑,正常执行完try中的代码,继续执行try...catch后边的代码
        4.如果try中产生了多个异常对象,就需要定义多个catch来捕获处理这些异常对象
    -------------------------------------------
    选中要添加try...catch的代码:按快捷键 ctrl+alt+t==>选择try...catch
 */
public class Demo06TryCatch {
    public static void main(String[] args) {
        try {
            //可能会产生异常的代码
            readFile("d:\\abc.java");
            //readFile(null);
            //readFile("c:\\a.txt");
        }catch (FileNotFoundException e){//FileNotFoundException e = new FileNotFoundException("您传递的路径不是d:\\abc.java");
            //异常的处理逻辑
            System.out.println("哈哈");
        }catch (IOException e) {//IOException e = new IOException("您传递的路径是null");
            //异常的处理逻辑
            System.out.println("呵呵");
        }
        System.out.println("后续代码!");
    }

    /*
        定义一个方法,方法的参数传递一个文件的路径:  d:\\abc.java
        在方法中根据文件的路径读取文件
     */
    public static void readFile(String path) throws FileNotFoundException,IOException{
        //判断路径path是否为null,是null抛出IOException
        if(path==null){
            throw new IOException("您传递的路径是null");
        }
        //判断路径path是否为d:\\abc.java,不是抛出FileNotFoundException
        if(!"d:\\abc.java".equals(path)){
            throw new FileNotFoundException("您传递的路径不是d:\\abc.java");
        }
        //根据路径读取文件
        System.out.println("读取到了d:\\abc.java文件,文件中的内容是abc!");
    }
}

8.Objects类中requireNonNull方法(了解)

package com.itheima.demo03Exception;

import java.util.Objects;

/*
    java.util.Objects:操作对象的工具类
    静态方法:容忍空指针安全的
    requireNonNull:判断传递的对象是否为null
        如果传递的对象是null,方法内部就会抛出空指针异常
        如果传递的对象不是null,则方法内部返回这个对象
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }
    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }
 */
public class Demo07Objects {
    public static void main(String[] args) {
        Person p = new Person();
        Person p2 = Objects.requireNonNull(p);
        System.out.println(p);//com.itheima.demo03Exception.Person@4554617c
        System.out.println(p2);//com.itheima.demo03Exception.Person@4554617c
        System.out.println(p==p2);//true
        Person p3 = null;
        //Person p4 = Objects.requireNonNull(p3);//NullPointerException
        Person p4 = Objects.requireNonNull(p3,"您传递的对象是null");//NullPointerException: 您传递的对象是null
        System.out.println(p4);
    }
}

9.Throwable类中定义的异常处理逻辑(了解)

package com.itheima.demo03Exception;

/*
    Throwable类中定义的异常处理逻辑(了解)
        仅供参考,我们可以使用处理异常的方式,也可以自己定义异常的处理方式
    Throwable类中定义的方法:
        String getMessage() 返回此 throwable 的简短描述。
        String toString()  返回此 throwable 的详细消息字符串。重写Object类的toStirng方法
        void printStackTrace()  JVM把异常信息打印在控制台,默认调用就是此方法
     Exception类继承了Throwable,所以Exception所有的子类都可以使用这个三个方法
 */
public class Demo08Throwable {
    public static void main(String[] args) /*throws Exception*/ {
        try {
            throw new Exception("异常了!");
        } catch (Exception e) {//Exception e = new Exception("异常了!");
            //异常的处理逻辑:可以是任意的代码
            //System.out.println("哈哈");

            //String getMessage() 返回此 throwable 的简短描述。
            //System.out.println(e.getMessage());//异常了!

            //String toString()  返回此 throwable 的详细消息字符串。重写Object类的toStirng方法
            //System.out.println(e.toString());//java.lang.Exception: 异常了!
            //System.out.println(e);//java.lang.Exception: 异常了!

            //void printStackTrace()  JVM把异常信息打印在控制台,默认调用就是此方法,打印的异常信息是最全面的
            e.printStackTrace();
            /*
                java.lang.Exception: 异常了!
	            at com.itheima.demo03Exception.Demo08Throwable.main(Demo08Throwable.java:15)
             */
        }
    }
}

10.finally关键字(重点)

finally关键字里边定义的代码,无论程序是否有异常,都会执行

package com.itheima.demo03Exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    finally关键字(重点)
    作用:
        finally关键字里边定义的代码,无论程序是否有异常,都会执行
        工作中一般用于资源释放(IO)
     格式:
        try{
            可能产生异常的代码
        }catch(定义一个异常相关的变量){
            异常的处理逻辑(想怎么写就怎么写)
        }
        ...
        catch(定义一个异常相关的变量){
            异常的处理逻辑(想怎么写就怎么写)
        }finally{
            无论是否异常,都会执行的代码
        }
   注意:
       1.finally关键字不能单独使用,必须和try一起使用
       2.如果try中出现了异常,会先执行catch中异常的处理逻辑,再执行finally中定义的代码
            执行完毕,继续执行try...catch...finally之后的代码
       3.如果try中没有出现异常,执行完try中的代码,再执行finally中定义的代码
            执行完毕,继续执行try...catch...finally之后的代码
 */
public class Demo09finally {
    public static void main(String[] args) throws ParseException {
        /*
            程序执行流程:
            没有异常:A==>C==>D
            有异常:B==>C==>D
         */
        /*try {
            //可能产生异常的代码
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse("2021-1129");
            System.out.println("A:"+date);
        } catch (ParseException e) {
            //异常的处理逻辑
            System.out.println("B:"+e.toString());
        } finally {
            //无论是否异常,都会执行的代码
            System.out.println("C:无论是否异常,都会执行的代码");
        }*/

        /*
            程序执行流程:
            没有异常:A==>C==>D
            有异常:C==>JVM终止程序
         */
        try {
            //可能产生异常的代码
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse("2021-1129");
            System.out.println("A:"+date);
        }finally {
            //无论是否异常,都会执行的代码
            System.out.println("C:无论是否异常,都会执行的代码");
        }
        System.out.println("D:后续代码!");
    }
}

11.异常处理的注意事项(了解)

1).运行时(期)异常

package com.itheima.demo04Exception;

/*
    异常的注意事项:
        1.运行时(期)异常被抛出可以不处理。
            即不捕获(不使用try...catch来捕获处理异常)
            也不声明抛出(不使用throws关键声明抛出异常)。
       运行时异常,我们无需处理,默认会交给JVM处理==>中断
       运行时异常,处理没有意义,处理了也是为了执行后续代码
       但是使用数组,超出了数组索引的使用范围,就算我们使用try...catch处理了运行时异常
       实际上数组还是越界
       这时候我们应该修改代码,不让数组的索引越界,从根本上解决问题
 */
public class Demo01Exception {
    public static void main(String[] args) {
        //使用try...catch,处理了运行时异常,也是为了执行后续代码,异常本身还存在
        /*try {
            int[] arr = {10,20,30};
            System.out.println(arr[3]);//throw new ArrayIndexOutOfBoundsException("3")
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        //在实际工作中:运行时异常修改代码,不让运行时异常出现,从根本上解决异常
        int[] arr = {10,20,30};
        System.out.println(arr[2]);
        System.out.println("后续代码!");
    }
}

2).子父类异常的处理

package com.itheima.demo04Exception;

public class Demo02Fu {
    public void show01()throws Exception{}

    public void show02()throws Exception{}
    
    public void show03()throws Exception{}

    public void show04(){}
}
package com.itheima.demo04Exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    异常处理的注意事项:
    2.子父类异常的处理
    a.如果父类的方法抛出了多个异常,
        子类重写父类方法时,子类可以抛出和父类相同的异常
        子类重写父类方法时,抛出父类异常的子类
        子类重写父类方法时,可以不抛出异常
    b.父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

    重点:
        父类异常什么样,子类重写父类方法就和父类一样就可以了,无需考虑异常问题
 */
public class Demo03Zi extends Demo02Fu {
    //子类重写父类方法时,子类可以抛出和父类相同的异常
    @Override
    public void show01()throws Exception{}

    //子类重写父类方法时,抛出父类异常的子类
    @Override
    //public void show02() throws NullPointerException { }
    //public void show02() throws ArrayIndexOutOfBoundsException { }
    public void show02() throws RuntimeException { }

    //子类重写父类方法时,可以不抛出异常
    @Override
    public void show03(){}

    //父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。
    //overridden method does not throw 'java.lang.Exception'
    //public void show04()throws Exception{}

    //此时子类产生该异常,只能捕获处理,不能声明抛出(throws处理异常的方式不能使用了)
    public void show04() {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse("2021-1129");
            System.out.println("A:"+date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

3).多个异常使用捕获又该如何处理

package com.itheima.demo04Exception;

import java.util.ArrayList;

/*
    异常处理的注意事项:
    多个异常使用捕获(try...catch)又该如何处理呢?
    1. 多个异常分别处理。
    2. 多个异常一次捕获,多次处理。
    3. 多个异常一次捕获一次处理。
 */
public class Demo04Exception {
    public static void main(String[] args) {
        //1. 多个异常分别处理:一个try catch处理一个异常
        /*try {
            int[] arr = {10,20,30};
            System.out.println(arr[3]);
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }

        try {
            ArrayList<String> list = new ArrayList<>();
            list.add("aaa");
            list.add("bbb");
            System.out.println(list.get(2));
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        }*/

        /*
            2. 多个异常一次捕获,多次处理。
            一次捕获:把所有的代码写在一个try中
            多次处理:一个异常使用一个catch处理
                每个catch中,都可以针对异常写特有的处理方式
         */
        /*try {
            int[] arr = {10,20,30};
            //System.out.println(arr[3]);

            ArrayList<String> list = new ArrayList<>();
            list.add("aaa");
            list.add("bbb");
            System.out.println(list.get(2));
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组索引越界了:"+e);
        }catch (IndexOutOfBoundsException e) {
            System.out.println("集合索引越界了:"+e);
        }*/

        //3. 多个异常一次捕获一次处理。
        try {
            int[] arr = {10,20,30};
            //System.out.println(arr[3]);

            ArrayList<String> list = new ArrayList<>();
            list.add("aaa");
            list.add("bbb");
            System.out.println(list.get(2));
        } catch (Exception e) {
            /*
                多态
                    Exception e = new ArrayIndexOutOfBoundsException();
                    Exception e = new IndexOutOfBoundsException();
             */
            e.printStackTrace();
        }

        System.out.println("后续代码!");
    }
}

package com.itheima.demo04Exception;

import java.util.ArrayList;

public class Demo05Exception {
    public static void main(String[] args) {
        /*
            2. 多个异常一次捕获,多次处理。
            一次捕获:把所有的代码写在一个try中
            多次处理:一个异常使用一个catch处理
                每个catch中,都可以针对异常写特有的处理方式
            注意:
                当多异常分别处理时,捕获处理,前边的类不能是后边类的父类
                 public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException
         */
        try {
            int[] arr = {10,20,30};
            //System.out.println(arr[3]);

            ArrayList<String> list = new ArrayList<>();
            list.add("aaa");
            list.add("bbb");
            System.out.println(list.get(2));
        }catch (IndexOutOfBoundsException e) {
            System.out.println("集合索引越界了:"+e);
        } /*catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组索引越界了:"+e);
        }*/
    }
}

请添加图片描述

12.自定义异常(使用)

自定义异常:自己定义一个异常类

1).概述和基本定义格式

package com.itheima.demo05Exception;

/*
    自定义异常:
        java给我们提供的异常类不够我们使用,就需要我们自己定义一些异常相关的类
    注意:
        1.自定义异常,一般都是以Exception结尾的,说着这个类是一个异常相关的类(见名知意)
        2.自定义异常
            a.可以继承Exception:自定义异常就是一个编译期异常
                使用:如果在方法内部抛出了编译期异常,那么我们就必须处理这个异常
                    1).使用throws在方法上声明抛出异常对象,最终抛出给JVM处理
                    2).使用try...catch自己捕获处理异常
           b.可以继承RuntimeException:自定义异常就是一个运行时异常
                使用:如果在方法内部抛出了运行时异常,我们无需处理,默认会交给JVM处理(中断)
    格式:
         public class xxxException  extends  Exception|RuntimeException{
            //定义一个空参数构造方法
            public xxxException(){
                super(); //调用父类的空参数构造方法
            }
            
            //定义一个带异常信息的构造方法
            //我们查询异常相关类的源码发现,每个异常类都会定义一个带异常信息的构造方法,把异常信息传递给父类处理
            public xxxException(String message){
                super(message); //调用父类带异常信息的构造方法
            }
         }                 
 */
public class RegisterException extends Exception|RuntimeException{
    public RegisterException() {
        super();
    }

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

2).自定义异常的使用

a.自定义异常类是编译异常:必须处理
package com.itheima.demo05MyException;

/*
    自定义异常:RegisterException 继承 Exception
    自定义异常:就是一个编译期异常
 */
public class RegisterException extends Exception{
    public RegisterException() {
        super();
    }

    public RegisterException(String message) {
        super(message);
    }
}
package com.itheima.demo05MyException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

/*
    自定义异常的使用
    注册案例:
        1.定义一个ArrayList集合,存储用户已经注册过的用户名
        2.使用Scanner获取一个用户本次输入的注册用户名
        3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
            a.遍历ArrayList集合,获取每一个已经注册的用户名
            b.使用已经注册的用户名和用户本次输入的用户名比较
                true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常
                false:继续遍历获取用户名比较
            c:遍历结束了,还没有找到相同的用户名
                 进行注册:把用户名存储到ArrayList集合中
                 提示用户"恭喜您xx名字注册成功!"
 */
public class Demo01Test {
    public static void main(String[] args) throws RegisterException {
        //1.定义一个ArrayList集合,存储用户已经注册过的用户名
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张三","李四","jack","rose");
        //2.使用Scanner获取一个用户本次输入的注册用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要注册的用户名:");
        String regName = sc.nextLine();
        //调用校验的方法
        checkName(list,regName);
    }

    //3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
    public static void checkName(ArrayList<String> list,String regName) throws RegisterException {
        //a.遍历ArrayList集合,获取每一个已经注册的用户名
        for (String name : list) {
            //b.使用已经注册的用户名和用户本次输入的用户名比较
            if(name.equals(regName)){
                //true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常(编译期异常,必须使用throws或者try...catch处理)
                throw new RegisterException("您输入的用户名["+regName+"]已经被注册了!");
            }
            //false:继续遍历获取用户名比较
        }
        //c:遍历结束了,还没有找到相同的用户名
        //进行注册:把用户名存储到ArrayList集合中
        list.add(regName);
        System.out.println(list);
        //提示用户"恭喜您xx名字注册成功!"
        System.out.println("恭喜您用户名["+regName+"]注册成功!");
    }
}
b.自定义异常是运行期异常:不用处理
package com.itheima.demo06MyException;

/*
    自定义异常:RegisterException 继承 RuntimeException
    自定义异常:就是一个运行期异常
 */
public class RegisterException extends RuntimeException{
    public RegisterException() {
        super();
    }

    public RegisterException(String message) {
        super(message);
    }
}
package com.itheima.demo06MyException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

/*
    自定义异常的使用
    注册案例:
        1.定义一个ArrayList集合,存储用户已经注册过的用户名
        2.使用Scanner获取一个用户本次输入的注册用户名
        3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
            a.遍历ArrayList集合,获取每一个已经注册的用户名
            b.使用已经注册的用户名和用户本次输入的用户名比较
                true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常
                false:继续遍历获取用户名比较
            c:遍历结束了,还没有找到相同的用户名
                 进行注册:把用户名存储到ArrayList集合中
                 提示用户"恭喜您xx名字注册成功!"
 */
public class Demo01Test {
    public static void main(String[] args)  {
        //1.定义一个ArrayList集合,存储用户已经注册过的用户名
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张三","李四","jack","rose");
        //2.使用Scanner获取一个用户本次输入的注册用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要注册的用户名:");
        String regName = sc.nextLine();
        //调用校验的方法
        checkName(list,regName);
    }

    //3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
    public static void checkName(ArrayList<String> list,String regName)  {
        //a.遍历ArrayList集合,获取每一个已经注册的用户名
        for (String name : list) {
            //b.使用已经注册的用户名和用户本次输入的用户名比较
            if(name.equals(regName)){
                //true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常(运行时异常,无需处理.默认交给JVM处理)
                throw new RegisterException("您输入的用户名["+regName+"]已经被注册了!");
            }
            //false:继续遍历获取用户名比较
        }
        //c:遍历结束了,还没有找到相同的用户名
        //进行注册:把用户名存储到ArrayList集合中
        list.add(regName);
        System.out.println(list);
        //提示用户"恭喜您xx名字注册成功!"
        System.out.println("恭喜您用户名["+regName+"]注册成功!");
    }
}

异常总结(重点中的重点):

请添加图片描述

package com.itheima.demo07Exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    异常:程序不正常
    throw:在方法中抛出指定的异常对象
        运行期异常对象:无需处理,默认交给JVM处理(中断)
        编译期异常对象:必须处理
    throws:异常处理的第一种方式,把异常对象抛出给方法的调用者处理,最终抛出给JVM(中断)
        最终抛给虚拟机,程序中断,无法执行后续代码
    try...catch:异常处理的第二种方式,使用try捕获异常对象,把异常对象抛给catch(接住)处理
        自己处理了异常,可以执行后续代码
    finally:无论程序是否有异常,都会执行finally中的代码
 */
public class Demo01Exception {
    public static void main(String[] args) /*throws Exception */{
        try {
            throw new Exception("长绿毛了!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("无论程序是否有异常,都会执行finally中的代码");
        }

        //ctrl+alt+t
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse("2021-1129");
            System.out.println("A:"+date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        System.out.println("后续代码!");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值