【Java24】异常,finally


1.错误和异常区别

package com.itheima01.throwable;
import java.util.Arrays;
//错误(Error) : 从程序角度 只能避开,不能解决。 异常(Exception) : 从程序角度 可以解决的问题
public class ThrowableDemo {
    
    
    public static void main(String[] args) {
    
       
        // int[] array = new int[3];
        //System.out.println(array); //[I@6d6f6e28
        //System.out.println(array.toString()); //[I@6d6f6e28
        //System.out.println(Arrays.toString(array)); //[0, 0, 0]   

// int[] array = new int[2_000_000_000]; //20亿撑不住,内存条不够
// System.out.println(Arrays.toString(array)); //java.lang.OutOfMemoryError: Java heap(堆) space //OOM :内存溢出【错误】
        int[] array = {
    
    };
        System.out.println(array[1]); //java.lang.ArrayIndexOutOfBoundsException【异常】
    }
}

在这里插入图片描述

package com.itheima02.jvm;
import java.util.ArrayList;
/*
*  throw 关键字(全小写): 1. 效果等同于return,后续代码不再执行
*       2. throw + Throwable对象(只能跟异常对象);  return 返回值;
*       3. 运用: 我们一般不使用, JDK方法的设计者 (抛出异常: api设计者 和 使用者交流方式)
*/
public class ThrowDemo {
    
    
    public static void main(String[] args) {
    
    
//        new ArrayList<String>(-1); //IllegalArgumentException
        int[] array = {
    
    0,1};
        int element = getElement(array);
        System.out.println(element);
    }
    
    private static int getElement(int[] array) {
    
    
        int index = 2;
        if(index > array.length - 1){
    
     //>2-1
            //访问了数组不存在的索引
//          ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("you are a stupid bird,you access a wrong index:" + index);
//          throw e; //抛出异常,下面代码不会执行。抛出去之后也没人处理	
					
            throw  new ArrayIndexOutOfBoundsException(index); //这一行等同上两行            
			//throw new Throwable(""); //也可以,因为是编译异常,声明getElement方法后要加throws Throwable
        }
        int element = array[index]; //上面有throw,这里两行都不执行
        return element;
    }
}

2.编译和运行异常

在这里插入图片描述

public class ExceptionDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        String str = "1996-01-01";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(sdf); //java.text.SimpleDateFormat@f67a0200
//       sdf.parse(str); //解析异常ParseException也叫编译异常,和IOException并列关系,main声明需抛出。
        Date parse = sdf.parse(str); //加上Date parse不报错
        System.out.println(parse); //Mon Jan 01 00:00:00 CST 1996

//        FileOutputStream fos = new FileOutputStream(""); //FileNotFoundException是IOException子类
//        fos.write(97); //IOException是最经典的编译异常

//111111111111111111111111111111111111111111111以下都为RuntimeException的子类
//       1.  NullPointerException  空指针
        String s = null;
//        System.out.println(s.length());

// 		2. IndexOutOfBoundsException  索引越界
        int[] array = {
    
    };
//        System.out.println(array[1]);

        // 3. ClassCastException  类转换
        // 4. IllegalArgumentException 非法参数
        new ArrayList<String>(-1);
    }
}

3.处理异常

在这里插入图片描述

package com.itheima03.throwsd;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ThrowsDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        method01(); //表哥又抛出去叫大哥(jvm,因为main方法调用者是jvm),jvm出错又打印终止
    } 
    /*
    *  throws 关键字
    *    1. 用在方法声明上: 修饰符 返回值类型 方法名(参数列表) throws 异常类型(A)
    *    2. 这是处理异常的一种方式: 声明将异常抛出给调用者处理(假手与人)
    *    3. 注意: 这里的异常类型A 必须跟方法里要抛出的异常B一致, 或者A是B的父类 (向上转型)
    *    4. 语法: throws 异常1,异常2{ }
    *    运用: 我们可以在某一方法的设计上先声明抛出异常,可以方法的调用处进行处理
    *         切记有有一环节必须处理, 不然到JVM中, 出现异常就崩溃
    *    我们平时学习为了省事, 如果明知不会错的异常,直接throws
    */
    private static void method01() throws IOException {
    
     //交给表哥 
        FileOutputStream fos = new FileOutputStream("a.txt");
        fos.write(97);
    }
}

在这里插入图片描述

package com.itheima04.trycatch;

public class TrycatchDemo {
    
    
    public static void main(String[] args) {
    
    
        int[] array = {
    
    0,1};
        try{
    
    
            int element = array[2];
            System.out.println(element);
        }catch (Exception e){
    
    
            e.printStackTrace();//打印异常信息: 打印栈中追溯,案发地点在方法栈中。jvm不会打印了,我们自己手动打印。这行注释了,下面就不会打印出异常。
            System.out.println("出现异常,并被捕获了");
        }
        System.out.println("程序继续执行");
    }
}

在这里插入图片描述

package com.itheima04.trycatch;
import java.util.Scanner;
/*
*   try...catch运用: 1. 如果代码都是由我们自己编写的,我们一般都不会出现异常
*        2. 有些代码需要用户参与编写 (交互: 我们程序输出,用户输入)
*思想: 我们预知代码可能运行结果(如果了包含了异常, 提前try...cath并给出提示或者解决方案)
*/
public class TryCatchDemo02 {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个被除数:");
        int a = sc.nextInt();
        
        System.out.println("请输入一个除数:");
        int b = sc.nextInt();        
        try {
    
                
            int result = a/b; //java.lang.ArithmeticException: / by zero  算术异常
            System.out.println(result);
        }catch (Exception e){
    
    
            System.out.println("你个傻鸟,除数不能为0");
        }
        System.out.println("软件继续让你玩");
    }
}
package com.itheima04.trycatch;
/*
      try{
       }catch (NullPointerException e){
           //1. 如果出现了空指针,应该提示...
       }catch (IndexOutOfBoundsException e2){
           //2. 如果出现了索引越界, 应该提示...
       }
       思想: 异常的分类讨论
       执行顺序:
            如果try中代码发生异常, 那么多个catch会从上到下逐一尝试捕获,
            如果被A捕获了,后续的catch不再执行
       注意:
            1. 前面catch中的异常类型不能是后面catch中的异常类型的父类或者相同 (因为这样的话,后续catch执行不到没有意义)
            2. 后面catch中的异常类型可以是前面的父类
*/
public class TryCatchCatchDemo {
    
    
    public static void main(String[] args) {
    
    
       try{
    
    
           method01(2);
       }catch (NullPointerException e){
    
    
           System.out.println("发生了空指针异常");
       }catch (IndexOutOfBoundsException e2){
    
    
           System.out.println("发生了索引越界异常");
       }
        System.out.println("代码继续执行");
    }
    
    //模拟: 这段代码可能有两个异常(一段代码里面不论可能有多少个异常,一次运行最多抛出一个异常)
    private static void method01(int a) {
    
    
        if(a == 1){
    
    
            throw new NullPointerException("空指针"); //throw天生与其他代码互斥,一旦发生throw,其他代码不再运行
        }else if(a == 2){
    
    
            throw new IndexOutOfBoundsException("越界异常");
        }else{
    
    
            System.out.println("什么事都没发生");
        }
    }
}

在这里插入图片描述

4.finally关键字

package com.itheima04.trycatch;
/*
        try{
        }catch (Exception e){
        }finally {
           // 无论如何,一定最后执行
        }
        作用: (IO流)释放资源。catch相当于else if,finally相当于else
*/
public class FinallyDemo {
    
    
    public static void main(String[] args) {
    
    
//        method();
       int number =  method2();  //运行 :3
        System.out.println(number);  //1
    }	

//111111111111111111111111111111111111111111111111111111111111111111111 
    private static int method2() {
    
    
        int i = 1;
        try{
    
    
//          System.exit(0); //拔电源阻止finally
            return i;  //一般return后续代码不会执行了,但finally会抢夺try...catch中的return执行权,finally会先执行,执行完又回到return  //return 安全机制: 把i的值给记录下来了1 ,所以return 1 
        }catch (Exception e){
    
     //没有异常,i永远不会=2
            i = 2;
        }finally {
    
    
            i = 3;
            System.out.println("运行 :" + i);
        }
        return i; //不执行,因为try catch finally有return了
    }

//11111111111111111111111111111111111111111111111111111111111111111111
    private static void method() {
    
    
        try{
    
    
            int i = 4/0;
            System.out.println(i);
        }catch (NullPointerException e){
    
    
            System.out.println("异常发生了");
        }finally {
    
    
            System.out.println("无论如何一定执行");
        }
        System.out.println("程序继续执行");
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.自定义异常

package com.itheima05.custom;
/*
*   JavaBean : 标准类 (封装)
*       1. private属性
*       2. public get set方法
*       3. public 空参构造,不声明构造会有一个空参构造
*		   写满参构造就得写空参构造
*   封装: 1. private属性 为了不对外直接暴露 -> 安全
*         2. public get set方法【方法跟属性最大不同, 方法可以加条件判断(健壮性校验)】
*   继承: 自定义异常
*/
public class Student {
    
    
    private String name;
    private int age;
    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public int getAge() {
    
    
        return age;
    }
    public void setAge(int age) {
    
    
        if(age < 0){
    
    
//            throw new IllegalArgumentException("你个傻鸟,age没有负数");
            throw new NoAgeException("你个傻鸟,age没有负数"); //不报错,因为下面class NoAgeException extends 。。。
        }
        this.age = age;
    }
}
package com.itheima05.custom;
/*
* 自定义异常: IllegalArgumentException : 非法参数异常
* NoAgeException : 非法年龄异常(框架: 很多JDK没有的异常,自定义)
*/
public class CustomDemo {
    
    
    public static void main(String[] args) {
    
    
        Student s = new Student();
        s.setName("张三");
//        s.age = -18; // 非法访问,安全隐患,所以private int age;
        s.setAge(-18); //在方法里加安全机制
        System.out.println(s);
    }
}
class NoAgeException extends IllegalArgumentException{
    
    
    public NoAgeException(String msg){
    
    
        super(msg); //调用IllegalArgumentException,Ill..又调用自己的super。。
    }
}

如下是方法重写注意事项:
在这里插入图片描述

package com.itheima06.notice;
import java.io.IOException;
/*
*   现象: 1. 父类 方法中声明编译异常【void method() throws IOException{}】,而子类没有声明编译异常 不会报错
*         2. 父类 方法中未声明编译异常,而子类有声明编译异常 会报错 !!!!!
*   解释: 现象2 跟 多态冲突了
*       1.现象2在多态中,编译器只看左边,父类方法没有编译异常,以为没有编译异常,不需要处理
*       2.运行看右边,子类重写的方法运行时有编译异常 (编译异常要求编译时期必须处理)
*       冲突: 编译异常 绕过了 编译器 (编译器强制报错)
*/
public class NoticeDemo {
    
    
    public static void main(String[] args) throws IOException {
    
           
        Fu fu = new Zi();  //编译看左边,运行看右边
        fu.method();
    }
}
class Fu{
    
    
    void method() {
    
    
    }
}
class Zi extends Fu{
    
    
    @Override
    void method() throws RuntimeException{
    
    //不报错 //throws IOException编译异常会报错,运行异常不报错。
    }
}

B站/知乎/微信公众号:码农编程录
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43435675/article/details/107522639