自定义异常
流程
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常对象
- 若在当前抛出异常的方法中处理异常,可以在当前抛出异常的方法外使用try-catch(抛出异常的方法放在try代码块中)捕获并处理
- 否则在方法声明处通过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
- 用在方法声明后面,跟着是异常类名
- 可以跟多个异常类名,用逗号隔开
- 表示抛出异常,由该方法的调用者处理
- 表示出现异常的一种可能性,但并不一定会发生这些异常
throw
- 用在方法体内,后面跟的是异常对象名
- 只能抛出一个异常对象名
- 表示抛出异常,由该方法体内的语句处理
- 执行throw一定抛出了某种异常
注意事项
- 通过throw抛出的异常一定需要用try-catch捕获,否则编译错误
- 不管是否使用自定义异常,都要养成永远不应当在main方法上使用throws的习惯!!!
参考文献:
- https://www.jb51.net/article/226124.htm
- https://wenku.baidu.com/view/94d409491db91a37f111f18583d049649b660eea.html