异常处理try-catch-finally/throws/throw/Exception

异常处理:

异常概述与异常体系结构

在这里插入图片描述

首先,我们有一个顶级的父类:class Throwable,这个父类下面有两个子类:class Error and class Exception 查看继承顺序,快捷键:ctrl+t

总的来说分为两个大类:Error / Exception

第一个是系统性的错误:比如Stack overflow Error and out of memory 这一类我们不展开讨论,主要说第二类

第二个又分为编译时异常(受检异常checked)与运行时异常(非受检异常unchecked)

  1. 编译时异常(checked)
    • IOException—FileNotFoundException
    • ClassNotFoundException
  2. 运行时异常(unchecked)
    • NullPointerException
    • ArrayIndexOutOfBoundsException
    • ClassCastException
    • NumberFormatException
    • InputMismatchException
    • ArithmeticException
public static void main(String[] args) {
	main(args);//StackoverflowError
	int[] arr=new int[2048*2048*2048];//heap space outof memory
	
	int[] arr1=null;
	System.out.println(arr1[3]);//NullPointerException
	
	int[] arr2=new int[5];
	System.out.println(arr2[6]);//ArrayIndexoutofBoundsException
	
	Object obj= new Date();
	String str=(String)obj;//ClassCastException
	
	String str1="123";
	str1="abc";
	int a=Integer.parseInt(str1);//NumberformatException
	
	Scanner scanner=new Scanner(System.in);
	int b=scanner.nextInt();//input number.if input other type,InputMismatchException
	System.out.println(b);
	
	int c=10,d=0;
	System.out.println(c/d);//ArithmeticException
}

面试题:你都遇见过哪些常见的异常?

在这里插入图片描述

在这里插入图片描述

try—catch—finally 快捷键:alt+shift+z

一、异常的处理:抓抛模型

  1. “抛”: 程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出,一旦抛出对象后,其后的代码将不再执行
  2. ”抓“:可以理解为异常的处理方式,try—catch—finally ; throws

二、 try—catch—finally的使用

try{
//可以出现异常的代码
}catch(异常类型1 变量名1){
//处理异常的方式1
}catch(异常类型2 变量名2){
//处理异常的方式2
}catch(异常类型3 变量名3){
//处理异常的方式3
}...
finally{
//一定会执行的代码
}

说明:
  1. finally是可选的
  2. 使用try将可能出现异常的代码另外装起来,如果执行到被装起来的语句出现了异常,就抛出对应异常类的对象,然后在到catch中进行匹配
  3. 一旦匹配到了一个catch,就进入相应的catch进行异常处理,一旦执行完对应catch里面的程序,就跳出try-catch结构(在没有finally的情况下),继续执行其后的代码
  4. catch中的异常类型如果满足了子父类关系,则要求子类声明在父类的上面,不然子类无法执行,则会报错
  5. 常见的异常对象处理方式:String getMessage() /printStackTrace()
  6. 在try结构中声明的变量,再出了try结构以后,就不能再被调用
  7. 使用了try—catch—finally以后,虽然编译没有异常了,但是运行时依旧可能会出现异常,需要继续去处理
  8. 开发中运行时异常比较常见,一般不会去try—catch—finally,因为没有意义。一般来说使用try—catch—finally就是在编译的时候。

finally的使用:

  1. finally是可选的
  2. finally中声明的是一定会被执行的代码。即使catch中又出现了异常,try中有return,catch中也有return等情况
  3. 像数据库连接、输入输出流、网络编程Socker等资源,JVM是不能自动回收的。我们需要进行资源释放,因为就将资源释放声明在finally中
package com.ErrorException.nonworking;

public class DealwithException {
public static void main(String[] args) {
	String string="123";
	String string2="abc";
	
	try {
		int num=Integer.parseInt(string2);
	}catch(NumberFormatException o) {
	System.out.println("数字转换异常");}
	catch(NullPointerException o) {
	System.out.println("空指针了哟");}
	
	int[] arr=null;
	try {
		System.out.println(arr[3]);
	}catch(NumberFormatException o) {
		System.out.println("数字转换异常");}
		catch(NullPointerException o) {
		System.out.println("空指针了哟");}
	finally {
		System.out.println("finally为必须执行的语句");
	}
		int[] arr1=new int[5];
				try {
		System.out.println(arr1[6]);
	}catch(NumberFormatException o) {
		System.out.println("数字转换异常");}
		catch(NullPointerException o) {
		System.out.println("空指针了哟");}
	    catch(ArrayIndexOutOfBoundsException o) {
	    	System.out.println("索引越界了哟");
	    }
	
	
}
}

throws+ 异常类型

抛出了异常类的对象,但是没用,并没有解决实际问题,异常处往下的代码也不执行了。try-catch-finally这种模式是实际解决问题的,两种方法一般是嵌套使用;如下代码
package com.ErrorException.nonworking;

import java.security.PublicKey;

import com.myobjectoriented3.nonworking.StaticTest;

public class ThrowsException {
public static void main(String[] args) {
method3();
System.out.println("能否执行这一行?");
}
public static  void method3() throws ArithmeticException{
	try {
		method2();
	}catch(ArithmeticException o) {
		System.out.println("A方法的异常以处理");
	}
}
	
//注意:被抛出的异常要满足异常类的对象,才会被抛出,不然还是异常
public  static void method2() throws ArithmeticException {
	int c=10,d=0;
	System.out.println(c/d);
	System.out.println("method2异常下面的一行");
}
}

总结:子类抛出的异常不能比父类抛出的大。如果父类的某个方法没有抛出异常,则子类重写的方法也不能抛!

上面讲的都是自动产生异常对象,接下来我们聊聊手动的:

手动产生一个异常对象,并抛出throw

  • throws是处理异常的一种方法,通常写在方法声明的后面。而throw是手动产生一个异常,然后抛出,通常写在方法体中
package com.ErrorException.nonworking;

public class ThrowTest {
	public static void main(String[] args) {
		Student stu=new Student();
		try {
			stu.setId(-100);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println(e.getMessage());
		}
		
		
	}
	
}
class Student{
	private int id;
	public void setId(int id)throws Exception{
		if(id>0)
			this.id=id;
		else 
			throw new Exception("输入的学号有误");
	}
	
}

用户自定义异常类:

根据具体情况去定义特定的异常类,见名知意

下面的第一份代码是我们自己定义的一个异常类,第二份代码是它的一个使用
package com.ErrorException.nonworking;

public class SelfException extends RuntimeException {
	 @java.io.Serial
	    static final long serialVersionUID = -7034897685745766939L;
	 public SelfException() {
		 super();
	 }
	 
	 public SelfException(String message) {
		 super(message);
	 }
	 
}

package com.ErrorException.nonworking;

public class ThrowTest {
	public static void main(String[] args) {
		Student stu=new Student();
		try {//try--catch具体的处理
			stu.setId(-100);
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			System.out.println(e.getMessage());
		}
		
		
	}
	
}
class Student{
	private int id;
	public void setId(int id) throws RuntimeException{//抛给父类
		if(id>0)
			this.id=id;
		else 
			throw new SelfException("您输入的学号有误,不能输入负数");//自定义的异常类
	}
	
}

在这里插入图片描述

主类代码:
package com.ErrorException.nonworking;

public class EcmDef {
public static void main(String[] args) {
	try {
	int i=Integer.parseInt(args[0]);
	int j=Integer.parseInt(args[1]);
	int result=ecm(i,j);
	System.out.println(result);//刚开始忘记写这一行代码了,导致没有结果,哈哈哈
	}catch(NumberFormatException e) {
		System.out.println("数据类型不一致");
	}catch(ArrayIndexOutOfBoundsException e) {
		System.out.println("缺少命令行参数");
	}catch(ArithmeticException e) {
		System.out.println("除0");
	}catch(EcDef e) {
		System.out.println("输入的数不能为负数!");
	}finally {}
	
	
}
public static int ecm(int i,int j) throws EcDef {
	if(i<0||j<0) 
		throw new EcDef("输入的数不能为负数!");
		return i/j;
	}
}

异常类代码
package com.ErrorException.nonworking;

public class EcDef extends Exception{
	@java.io.Serial
    static final long serialVersionUID = -3387516993924229948L;
   public EcDef() {
	   super();
   }
   
   public EcDef(String message) {
	   super(message);
   }
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值