转自https://www.cnblogs.com/alsf/p/5626384.html
throw与throws两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
throws关键字
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
使用格式为:
public 返回值类型 方法名称(参数列表,,,)throws 异常类{};
假设定义一个除法,对于除法操作可能出现异常,可能不会。所以对于这种方法最好将它使用throws关键字声明,一旦出现异常,
则应该交给调用处处理。
class Math{
public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理
int temp = i / j ; // 计算,但是此处有可能出现异常
return temp ;
}
};
public class ThrowsDemo01{
public static void main(String args[]){
Math m = new Math() ; // 实例化Math类对象
try{
System.out.println("除法操作:" + m.div(10,2)) ;
}catch(Exception e){
e.printStackTrace() ; // 打印异常
}
}
};
因为div使用了throws关键字声明,所以调用此方法的时候,方法必须进行异常处理。通过try...catch;
如果在主方法的声明也使用了throws关键字呢,那么是不是意味着主方法也可以不处理异常。
class Math{
public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理
int temp = i / j ; // 计算,但是此处有可能出现异常
return temp ;
}
};
public class ThrowsDemo02{
// 在主方法中的所有异常都可以不使用try...catch进行处理
public static void main(String args[]) throws Exception{
Math m = new Math() ; // 实例化Math类对象
System.out.println("除法操作:" + m.div(10,0)) ;
}
};
运行结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at methoud.Math.div(ThisDemo06.java:4)
at methoud.ThisDemo06.main(ThisDemo06.java:12)
在本程序中,主方法不处理任何异常,而交给JAVA中最大头JVM,所以如果在主方法使用了throws关键字,则表示一切异常
交给JVM进行处理。默认处理方式也是JVM完成。
throw关键字
throw关键字作用是抛出一个异常,抛出的时候是抛出的是一个异常类的实例化对象,
在异常处理中,try语句要捕获的是一个异常对象,那么此异常对象也可以自己抛出。
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常
package methoud;
public class ThisDemo06{
public static void main(String args[]){
try{
throw new Exception("自己抛着玩的。") ; // 抛出异常的实例化对象
}catch(Exception e){
System.out.println(e) ;
}
}
};
范例,throw与throws的应用
在一般开发中,try,,catch,,finally,throw,throws联合使用的情况是最多的。try-finally可以单独使用,而不必加catch。
例如,现在要使用一个相除的方法,但是在操作之前必须打印“运算开始”的信息,结束之后必须打印“异常结束”。
如果有异常,需要把异常交给异常调用处处理。面对这样要求,必须全部使用以上关键字。
class Math{
public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理
System.out.println("***** 计算开始 *****") ;
int temp = i / j ; // 计算,但是此处有可能出现异常
System.out.println("***** 计算结束 *****") ;
return temp ;
}
};
public class ThrowDemo02{
public static void main(String args[]){
Math m = new Math() ;
try{
System.out.println("除法操作:" + m.div(10,0)) ;
}catch(Exception e){
System.out.println("异常产生:" + e) ;
}
}
};
运行结果:
***** 计算开始 *****
异常产生:java.lang.ArithmeticException: / by zero
以上没有计算结束,因为没有异常发生了,直接中断程序操作。所以做以下操作。
package methoud;
class Math{
public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理
System.out.println("***** 计算开始 *****") ;
int temp = 0 ; // 定义局部变量
try{
temp = i / j ; // 计算,但是此处有可能出现异常
}catch(Exception e){
}
System.out.println("***** 计算结束 *****") ;
return temp ;
}
};
public class ThisDemo06{
public static void main(String args[]){
Math m = new Math() ;
try{
System.out.println("除法操作:" + m.div(10,0)) ;
}catch(Exception e){
System.out.println("异常产生:" + e) ;
}
}
};
运行结果:
***** 计算开始 *****
***** 计算结束 *****
异常产生:java.lang.ArithmeticException: / by zero
这里虽然貌似成功了,但是,这里的异常并没有抛出去,因为在方法中已经被自动处理了,没有抛出去。
所以要抛出异常对象,给方法调用处处理,使用throw关键字。
package methoud;
class Math{
public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理
System.out.println("***** 计算开始 *****") ;
int temp = 0 ; // 定义局部变量
try{
temp = i / j ; // 计算,但是此处有可能出现异常
}catch(Exception e){
throw e ; //抛出异常。
}finally{ // 不管是否有异常,都要执行统一出口
System.out.println("***** 计算结束 *****") ;
}
return temp ;
}
};
public class ThisDemo06{
public static void main(String args[]){
Math m = new Math() ;
try{
System.out.println("除法操作:" + m.div(10,0)) ;
}catch(Exception e){
System.out.println("异常产生:" + e) ;
}
}
};
Exception与RuntimeException区别
是面试中经常出现的问题。
观察以下代码:
package methoud;
public class ThisDemo06{
public static void main(String args[]){
String str = "123" ; // 定义字符串,全部由数字组成
int temp = Integer.parseInt(str) ; // 将字符串变为int类型
System.out.println(temp * temp) ; // 计算乘方
}
};
parseInt()的定义格式:
public static int parseInt(String s) throws NumberFormatException
此方法明明使用了throws关键字抛出异常,为什么不用处理,也可以编译通过?
在JAVA异常处理机制中,
1)如果抛出的是EXception的类型,则必须进行try ..catch进行处理。
2)如果抛出的是RuntimeException的类型,则可以不使用try。。catch处理,一旦发生异常之后,将由JVM处理。这属于系统自动抛异常。
为了保证程序的健康性,在有可能出现异常的时候还是老实使用try ..catch处理。
自定义异常类。
只需要继承Exception类就可以自定义异常类。因为JAVA中提供的都是标准异常类(包括一些异常信息),如果需要自己想要
的异常信息就可以自定义异常类。
class MyException extends Exception{ // 自定义异常类,继承Exception类
public MyException(String msg){
super(msg) ; // 调用Exception类中有一个参数的构造方法,传递错误信息
}
};
public class DefaultException{
public static void main(String args[]){
try{
throw new MyException("自定义异常。") ; // 抛出异常
}catch(Exception e){
System.out.println(e) ; //打印错误信息
}
}
}
运行结果:
methoud.MyException: 自定义异常。
总结
throw与throws关键字联合使用问题。
1)throw:抛出异常。
2)throws:在方法声明处使用,表示此方法不处理异常,而在调用此方法处处理异常。
Exception是必须处理的,而RuntimeException异常是可以不处理的。但是为了保证程序正常运行,最好处理。
如果自定义异常,直接继承异常即可。