所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,但是一般情况下Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行。
throw 指的是语句抛出异常,后面跟的是对象,如:throw new ExceArithmeticException(),一般用于主动抛出某种特定的异常
例一:
public static void throwTest1(int a,int b) {
if(b==0){
throw new ArithmeticException("发生了算术错误异常");
}
System.out.println(b / a);
}
public static void main(String[] args) {
throwTest1(3,0);
}
}
结果:
例二:
public static void throwTest2( String string) {
if ("abc".equals(string)) {
throw new NumberFormatException("发生了数字转化格式异常");
} else {
System.out.println(string);
}
}
public static void main(String[] args) {
throwTest2("abc");
}
}
输出:
/**
* 当 throw 语句执行时,它后面的语句将不执行,
* 此时程序转向调用者程序,寻找与之相匹配的 catch 语句,
* 执行相应的异常处理程序。如果没有找到相匹配的 catch 语句,
* 则再转向上一层的调用程序。这样逐层向上,直到最外层的异常处理程序终止程序并打印出调用栈情况。
*/
如下所示:
public static void getLenth(int a){
if(a>8){
throw new IllegalArgumentException("用户名长度必须大于 8 位!");
}else if(a==0){
throw new ArithmeticException("发生了算术错误异常不能等于0");
}
}
try {
getLenth(9);
} catch (ArithmeticException e) {
// TODO: handle exception
System.out.println("test() -- 算术异常!");
}catch (IllegalArgumentException e){
System.out.println("长度大于8");
}
//输出结果:长度大于8
-------------------------------------------------------
try {
getLenth(0);
} catch (ArithmeticException e) {
// TODO: handle exception
System.out.println("test() -- 算术异常!");
}catch (IllegalArgumentException e){
System.out.println("长度大于8");
}
//输出结果 :test() -- 算术异常!
/**
* throws 用于方法名后,声明方法可能抛出的异常,然后交给调用其方法的程序处理
* 使用 throws 声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该由向上一级的调用者处理;
* 如果有多个异常类,它们之间用逗号分隔
*/
public static void count(int a,int b) throws ArithmeticException,RuntimeException{
System.out.println(a/b);
}
public static void main(String[] args) {
try {
count(3,0);
} catch (ArithmeticException e) {
// TODO: handle exception
System.out.println("test() -- 算术异常!");
}catch (RuntimeException e){
System.out.println("test() -- 运行异常!");
}
}
/**
* 使用 throws 声明抛出异常时有一个限制,是方法重写中的一条规则:
* 子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,
* 子类方法声明抛出的异常不允许比父类方法声明抛出的异常多
**/
如下所示:
public class OverrideThrows {
public void test() throws IOException {
FileInputStream fis = new FileInputStream("a.txt");
}
}
class Sub extends OverrideThrows {
// 子类方法声明抛出了比父类方法更大的异常
// 所以下面方法出错
public void test() throws Exception {
}
}
总结:
1、通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw 声明一个具体的异常信息。(throw 出现在方法体内部,而 throws 出现方法名后)
2、throw 表示抛出了异常,执行 throw 则一定抛出了某种特定异常,而 throws 表示方法执行可能会抛出异常,但方法执行并不一定发生异常
3、throws 通常不用显示地捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法; throw 则需要用户自己捕获相关的异常,而后再对其进行相关包装,最后将包装后的异常信息抛出。