在计算机程序的运行过程中,往往会出现各种各样的错误,因为有一些错误是程序员也无法避免的,比如说,输入框希望用户输入int类型的数字-年龄,但用户输入的是字符串“jsfg”,程序想要读取某个文件时,但用户已经将文件删除。
还有一些错误是随机出现的,并且永远不可能避免的,比如:
Java的异常体系如下图
如图,Throwable是异常类的最高父类,Error错误类和Exception异常类都继承自Throwable类。
Error表示严重的错误,程序对此一般无能为力,例如:
Exception是运行时的错误,并且它可以捕获并处理,例:
还有一些程序编写时逻辑错误造成的运行时异常,例:
Exception又分为两大类:
处理异常通常用到try....catch....finally throw和throws五个关键字
try....catch语句用法:把可能发生异常的代码放到try{......}中,再用catch捕获对应的Exception异常及其子类,示例如下:
import java.math.*;
public class demo01 {
public static void main(String[] args) {
try{
String str=String.format("%(%d)",11,11*13 );
System.out.println(str);
int[] ns= {};
ns[0]=1;
int[] n=null;
n[0]=1;
String s="32s";
int n1=Integer.parseInt(s);
System.out.println(n1*10);
}catch(ArrayIndexOutOfBoundsException ex) {
System.out.println("数组下标越界!!!");
}catch(NullPointerException ex) {
System.out.println("空指针了!!!");
}catch(NumberFormatException ex) {
System.out.println("数字格式化错误了!!!");
}catch(Exception ex) {
System.out.println("出错了!!!");
}
}
}
在JAVA中凡是可能抛出异常的语句,都可以用 try....catch捕获。把可能发生异常的语句放在try{.....}中,然后使用catch捕获对应的Exception及其子类,可以使用多个catch语句,每个catch分别捕获对应的异常类型,JVM在捕获到异常后,会从上到下匹配catch语句,匹配到某个catch后,执行catch代码块,然后不再继续匹配。
finally关键字用法:将无论有没有异常都需要执行的代码写道到finally{.....}里,例:
import java.util.Scanner;
public class demo03 {
public static void main(String[] args) {
Scanner input=null;
try {
input=new Scanner(System.in);
int n=input.nextInt();
System.out.println(n+10);
}catch(Exception ex) {
System.out.println("出错了!!!");
}finally{
input.close();
}
}
}
throws用来声明异常, throw用来抛出异常。
注意:
如果抛出RuntimeEception运行时异常,可以省略异常类型的方法声明throws RuntimeEception
如果抛出检查异常("编译器异常"),必须完成异常类型的方法声明throws NotEnoughException
自定义异常:
在一个大型的项目中,我们可以自定义一个新的异常类型,使这个自定义异常继承Exception异常
示例如下:
class demoo4 {
public static void main(String[] args) {
String str="唧唧复唧唧木兰当户织";
String d=copy(str,2,5);
System.out.println(d);
}
public static String copy(String s,int beginIndex,int endIndex) {
if(s==null) {
NullPointerException ex=new NullPointerException("空指针了!!!");
throw ex;
}if(beginIndex>=endIndex) {
throw new IllegalArgumentException("开始下标不能大于结束下标!!!");
}if(beginIndex<0||endIndex>s.length()) {
throw new StringIndexOutOfBoundsException("下标超出");
}
char[] arr=s.toCharArray();
StringBuilder sb=new StringBuilder();
for(int i=beginIndex;i<=endIndex;i++) {
char c=arr[i];
sb.append(c);
}
return sb.toString();
}
}
import java.rmi.NotBoundException;
public class demo05 {
public static void main(String[] args) throws NotEnoughException{
System.out.println("原始库存数量:"+Reposistory.stock);
//入库
Reposistory.in(50);
System.out.println("入库50件后,库存数量:"+Reposistory.stock);
// Reposistory.out(1000);
try {
Reposistory.out(1000);
System.out.println("出库1000件后,库存数量:"+Reposistory.stock);
}catch(IllegalArgumentException e) {
// System.out.println("出错");
}catch(NotEnoughException e) {
// System.out.println("出错了");
}
}
}
class Reposistory{
static int stock=100; //库存数量
public static void in(int count) {
stock=stock+count;
}
public static void out(int count) throws NotEnoughException {
if(count>stock) {
//如果抛出RuntimeEception运行时异常,
//可以省略异常类型的方法声明throws RuntimeEception
//throw new RuntimeEception("库存不足")
//如果抛出检查异常("编译器异常")
//必须完成异常类型的方法声明throws NotEnoughException
throw new NotEnoughException();
}
stock=stock-count;
}
}
class NotEnoughException extends Exception{
public NotEnoughException() {
super("库存不足");
}
}