【JAVASE】自定义异常以及throws与throw的区别

自定义异常

流程

  1. 创建自定义异常类
  2. 在方法中通过throw关键字抛出异常对象
  3. 若在当前抛出异常的方法中处理异常,可以在当前抛出异常的方法外使用try-catch(抛出异常的方法放在try代码块中)捕获并处理
  4. 否则在方法声明处通过throws关键字指明要抛出给方法调用者的异常

创建自定义异常类

class MyException extends Exception{
	public MyException(String ErrorMessage){
		super(ErrorMessage);//执行父类的(含参)构造函数
	}
}

super

super与this关键字用法相似

  • this:表示本类对象的引用
  • super:表示父类对象的引用

访问成员变量:super.成员变量
访问构造方法:super(…)
访问成员方法:super.成员方法()

而this的方法与上述一样
用一个普通的例子来解释super的作用

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new MyException("错误调用!");
	}

}
class parentException{
	public parentException(String Errormessage) {
		// TODO Auto-generated constructor stub
		System.out.println("父类异常类被调用!");
	}
	
}

class MyException extends parentException{
	public MyException(String ErrorMessage){
		super(ErrorMessage);//执行父类的(含参)构造函数
		System.out.println("自定义异常类被调用!");
	}
}

输出:

父类异常类被调用!
自定义异常类被调用!

所以,当创建一个自定义异常类对象时,会将错误信息向上抛出,也就是构造一个父类的对象。

通过throw关键字处理异常

对应上述流程3的第一种情况

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a=1,b=0;
		try {
			divide(a, b);
		} catch (MyException e) {
			// TODO: handle exception
			System.out.println(e);//e包含错误信息
		}catch (ArithmeticException e) {
			// TODO: handle exception
			System.out.println(e);
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
	public static void divide(int a,int b) throws MyException {
		if(b==0) {
			throw new MyException("除数不能为0!");
		}
	}

}

class MyException extends Exception{
	public MyException(String ErrorMessage){
		super(ErrorMessage);//执行父类的(含参)构造函数
		
	}
}

从代码中可以看到MyException -> ArithmeticException -> Exception需要服从从小范围到大范围的原则,否则小范围的异常将永远无法抛出!

通过throws关键字抛出异常

对应上述流程3的第二种情况

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a=1,b=0;
		try {
			divide(a, b);
		} catch (MyException e) {
			// TODO: handle exception
			System.out.println(e);//e包含错误信息
			System.out.println("自定义");
		}catch (ArithmeticException e) {
			// TODO: handle exception
			System.out.println(e);
			System.out.println("math");
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
	public static void divide(int a,int b) throws MyException {
		int c = a/b;
	}

}

class MyException extends Exception{
	public MyException(String ErrorMessage){
		super(ErrorMessage);//执行父类的(含参)构造函数
		
	}
}

输出:

java.lang.ArithmeticException: / by zero
math

可以看到通过throws抛出的异常自定义的MyException类并未捕捉,是因为MyException中没有throw抛出异常,而第二个catch ArithmeticException正好有处理该异常的方法(有throw),于是在第二个catch中被捕获,当第二个catch未捕捉到时就会经过第三个catch…
而当所有catch都未捕捉到时,会经过最后一个catch的异常类的super将异常向上抛出,但这时的异常会被抛出并终止程序的运行。

通过上述分析,那么是不是没有super也是可以的呢?

无super的情况

package Lab5;

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a=1,b=0;
		try {
			divide(a, b);
		} catch (MyException e) {
			// TODO: handle exception
			System.out.println(e);//e包含错误信息
			System.out.println("自定义");
		}catch (ClassCastException e) {
			// TODO: handle exception
			System.out.println(e);
			System.out.println("classCast");
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
			System.out.println("轮不到!");
		}
	}
	public static void divide(int a,int b) throws MyException {
		int c =a/b;
	}

}

class MyException extends Exception{
	public MyException(String ErrorMessage){
		
		
	}
}

输出:

java.lang.ArithmeticException: / by zero
轮不到!

package Lab5;

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a=1,b=0;
		try {
			divide(a, b);
		} catch (MyException e) {
			// TODO: handle exception
			System.out.println(e);//e包含错误信息
			System.out.println("自定义");
		}
	}
	public static void divide(int a,int b) throws MyException {
		
		if(b==0)throw new MyException("000");
	}

}


class MyException extends Exception{
	public MyException(String ErrorMessage){
		
		
	}
}

经过验证,是可以的,但是必须确保异常被catch捕获(可以是自定义异常类的catch也可以是别的),否则也是会因为编译错误而终止程序运行。

总结

throws 和 throw的区别

throws

  1. 用在方法声明后面,跟着是异常类名
  2. 可以跟多个异常类名,用逗号隔开
  3. 表示抛出异常,由该方法的调用者处理
  4. 表示出现异常的一种可能性,但并不一定会发生这些异常

throw

  1. 用在方法体内,后面跟的是异常对象名
  2. 只能抛出一个异常对象名
  3. 表示抛出异常,由该方法体内的语句处理
  4. 执行throw一定抛出了某种异常

注意事项

  1. 通过throw抛出的异常一定需要用try-catch捕获,否则编译错误
  2. 不管是否使用自定义异常,都要养成永远不应当在main方法上使用throws的习惯!!!

参考文献:

  1. https://www.jb51.net/article/226124.htm
  2. https://wenku.baidu.com/view/94d409491db91a37f111f18583d049649b660eea.html
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LenckCuak

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值