1、前言:什么是异常处理机制?
我们先从例子来引入Java的异常处理机制。
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/* 定义一个长度10的 数组*/
int[] a = new int[10];
int idx;
/*用户输入数字*/
System.out.println("Please Entry number:");
Scanner in = new Scanner(System.in);
idx = in.nextInt();
/*
定义a[x],当用户输入x时,则输出x
但因为定义的数组长度10,所以用户输入[0~9]以外会报错
* */
a[idx]=idx;
System.out.println("User Entry:"+a[idx]);
}
}
通过上述例子,我们不难看出,当用户输入【0~9】以外的数,就会报错。那如何处理这种异常呢?
Java把可能发生错误的异常放在try;把处理异常的方法写在catch中。
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/* 定义一个长度10的 数组*/
int[] a = new int[10];
int idx;
/*用户输入数字*/
System.out.println("Please Entry number:");
Scanner in = new Scanner(System.in);
idx = in.nextInt();
/*
定义a[x],当用户输入x时,则输出x
但因为定义的数组长度10,所以用户输入[0~9]以外会报错
* */
try {
a[idx] = idx;
System.out.println("User Entry:" + a[idx]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("User Entry error");
}
}
}
2、try-catch案例
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void fa() {
int a[] = new int[2];
a[2]=1;
/* 遇到异常后下面的代码不执行 */
System.out.println("hello1");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
fa();
System.out.println("hello2");
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("catch");
}
/*
如果catch能匹配到的话,执行下面的代码,如何执行不到则报错
例如把上面的catch换成例如把上面的catch换成NullPointerException
*/
System.out.println("hello3");
}
}
e.getMessage()获取是哪个错误
e.printStackTrace();获取异常堆栈,根据堆栈从下往上追溯
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void fa() {
int a[] = new int[2];
a[2]=1;
/* 遇到异常后下面的代码不执行 */
System.out.println("hello1");
}
public static void main(String[] args) {
try {
fa();
System.out.println("hello2");
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("catch");
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
}
/*
如果catch能匹配到的话,执行下面的代码,如何执行不到则报错
例如把上面的catch换成例如把上面的catch换成NullPointerException
*/
System.out.println("hello3");
}
}
3、throw e;再次抛出
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void fa() {
int a[] = new int[2];
a[2]=1;
/* 遇到异常后下面的代码不执行 */
System.out.println("hello1");
}
public static void aaa(){
try{
fa();
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("catch1");
}
}
public static void main(String[] args) {
try {
aaa();
System.out.println("hello2");
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("catch2");
}
/*
如果catch能匹配到的话,执行下面的代码,如何执行不到则报错
例如把上面的catch换成例如把上面的catch换成NullPointerException
*/
System.out.println("hello3");
}
}
根据上述代码,我们不难发现,如果被一次catch匹配后,后面的catch就不会执行【catch2不输出】,如果我们需要catch2也要输出,那应该如何处理?
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void fa() {
int a[] = new int[2];
a[2]=1;
/* 遇到异常后下面的代码不执行 */
System.out.println("hello1");
}
public static void aaa(){
try{
fa();
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("catch1");
throw e;
}
}
public static void main(String[] args) {
try {
aaa();
System.out.println("hello2");
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("catch2");
}
/*
如果catch能匹配到的话,执行下面的代码,如何执行不到则报错
例如把上面的catch换成例如把上面的catch换成NullPointerException
*/
System.out.println("hello3");
}
}
结果显示:catch1和catch2的异常都抛出了,但注意【hello2】不输出
4、finally跳出异常前执行
package com.company;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import java.util.Scanner;
public class Main {
public static void fa() {
int a[] = new int[2];
a[2]=1;
/* 遇到异常后下面的代码不执行 */
System.out.println("hello1");
}
public static void aaa(){
try{
fa();
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("catch1");
throw e;
}
}
public static void main(String[] args) {
try {
aaa();
System.out.println("hello2");
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("catch2");
}
finally {
System.out.println("插入日志");
}
/*
如果catch能匹配到的话,执行下面的代码,如何执行不到则报错
例如把上面的catch换成例如把上面的catch换成NullPointerException
*/
System.out.println("hello3");
}
}
5、如何进行自定义异常
先创建InsufficientFundsException.java
package catchtest;
import java.io.*;
public class InsufficientFundsException extends Exception
{
//此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱
private double amount;
public InsufficientFundsException(double amount)
{
this.amount = amount;
}
public double getAmount()
{
return amount;
}
}
创建CheckingAccount.java
package catchtest;
import java.util.Scanner;
public class CheckingAccount {
private double balance;
private int number;
public CheckingAccount(int number)
{
this.number = number;
}
//存钱
public void deposit(double amount)
{
balance += amount;
}
//取钱
public void withdraw(double amount) throws InsufficientFundsException
{
if(amount <= balance)
{
balance -= amount;
}
else{
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
}
//方法:返回余额
public double getBalance()
{
return balance;
}
//方法:返回卡号
public int getNumber()
{
return number;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CheckingAccount c = new CheckingAccount(101);
System.out.println("存入: $500...");
c.deposit(500.00);
System.out.println("您的余额:"+c.getBalance());
try {
Scanner in = new Scanner(System.in);
Double Double1 = Double.valueOf(in.nextLine().toString());
System.out.println("\n正在取出"+Double1);
c.withdraw(Double1);
} catch (InsufficientFundsException e) {
// TODO Auto-generated catch block
System.out.println("Sorry, 你还差 $"
+ e.getAmount());
} catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("您的余额:"+c.getBalance());
}
}
}