try
块后面可以接零个或多个 catch
块,如果没有 catch
块,则必须跟一个 finally
块。
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
try
{
// 程序代码
}catch(ExceptionName e1)
{
//Catch 块
}
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。
如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
下面的例子中声明有两个元素的一个数组,当代码试图访问数组的第四个元素的时候就会抛出一个异常。
// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{
public static void main(String args[]){
try{
int a[] = new int[2];
System.out.println("Access element three :" + a[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Exception thrown :" + e);
}
System.out.println("Out of the block");
}
}
以上代码编译运行输出结果如下:
Exception thrown:java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
多重捕获块的语法如下所示:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型3 异常的变量名3){
// 程序代码
}
上面的代码段包含了 3 个 catch块。
可以在 try 语句后面添加任意数量的 catch 块。
如果保护代码中发生异常,异常被抛给第一个 catch 块。
如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。
如果不匹配,它会被传递给第二个 catch 块。
如此,直到异常被捕获或者通过所有的 catch 块。
该实例展示了怎么使用多重 try/catch。
try {
file = new FileInputStream(fileName);
x = (byte) file.read();
} catch(FileNotFoundException f) { // Not valid!
f.printStackTrace();
return -1;
} catch(IOException i) {
i.printStackTrace();
return -1;
}
throws
语句用在方法定义时声明该方法要抛出异常类型。public void menthod() throws Exception1,Exception2,Exception3,...,ExceptionN{
//可能产生的异常
}
throw
用来抛出一个异常。throw new IOException();
throw
抛出的只能够是可抛出类Throwable
或者其子类的实例对象。throw new String("出错啦");
是错误的方案一:自己抛出的异常,自己处理。
public void method(){
try{
//代码段1
throw new 异常类型( );
}catch (异常类型 ex){
//对异常进行处理的代码段2
}
}
public class TryDemoOne {
public static void main(String[] args) {
testAge();
}
public static void testAge(){
try {
System.out.print("请输入年龄:");
Scanner sc=new Scanner(System.in);
int age= sc.nextInt();
if (age<18 || age>80){
throw new Exception("18岁一下,80岁以上需要陪同才能入住。");
}else {
System.out.println("欢迎入住。");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
方案二:谁调用了当前方法谁处理
public void method() throws 异常类型{
//代码段1
throw new 异常类型( );
}
public class TryDemoTne {
public static void main(String[] args) {
try {
testAge();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testAge() throws Exception{
System.out.print("请输入年龄:");
Scanner sc = new Scanner(System.in);
int age = sc.nextInt();
if (age < 18 || age > 80) {
throw new Exception("18岁一下,80岁以上需要陪同才能入住。");
} else {
System.out.println("欢迎入住。");
}
}
}
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后,语法如下:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
public class ExcepTest{
public static void main(String args[]){
int a[] = new int[2];
try{
System.out.println("Access element three :" + a[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Exception thrown :" + e);
}
finally{
a[0] = 6;
System.out.println("First element value: " +a[0]);
System.out.println("The finally statement is executed");
}
}java
}
以上实例编译运行结果如下:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed
throw 异常对象; 或 throw new 异常类型(参数列表);
try...catch...finally
进行处理,也可以借由 throws
通知方法调用者,应用时在进行处理。throw
抛出的异常是一定会产生的。throw
抛出的是 CheckedException
对象,且未进行处理,会编译报错;如抛出的是 UncheckedException
对象,则默认不会产生错误提醒。当然更推荐进行处理操作,以避免后续不必要的错误。throw
和return
都会触发方法中断操作,因此在未加入判断的情况下,不可同时出现。如图:错误提醒为:Unreachable code
当加入if判断后,错误提示消失。
throws
异常类型列表
如图,getResult
方法中, 针对输入数据可能不是5的倍数的情况,通过throw
抛出异常,并设定 异常描述信息,所抛出的异常由方法内部自行try.. catch
处理。
修订代码,如图,getResult
方法中并不自行处理,而通过throws
向 上级调用者抛出,由调用者自行决定处理方式。
再次修订代码,如图,getResult
方法中对throw
产生的异常既不自行处理,也不向上抛出,则会产生错误提示: Unhandled exception type Exception
。
继续修订代码,如图,修改getResult
方法中异 常为ArithmeticException
,于其属于UncheckedException
,则不会产生编译错误提示。
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
可以像下面这样定义自己的异常类:
public class HotelAgeException extends Exception{
public HotelAgeException(){
super("18岁一下,80岁以上需要陪同才能入住。");
}
}
getMessag( )
、toString()
和printStackTrace( )
在异常处理中的区别是什么?e.toString()
:获得异常类型和描述信息,当直接输出对象e时,默认调用e. toString()
方法。e.getMessage()
:获得异常描述信息e.printStackTrace()
:打印出异常产生的堆栈信息,包括种类、描述信息、出错位置等有时候我们会捕获一个异常后在抛出一个异常
顾名思义:将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,这样逐层抛出。
public class TryDemoFive {
public static void main(String[] args) {
try {
testThree();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testOne() throws HotelAgeException {
throw new HotelAgeException();
}
public static void testTwo() throws Exception {
try {
testOne();
} catch (HotelAgeException e) {
throw new Exception("我是新产生的异常1",e);
}
}
public static void testThree() throws Exception {
try {
testTwo();
} catch (Exception e) {
Exception e1=new Exception("我是新产生的异常2");
e1.initCause(e);
throw e1;
}
}
}