要明白Java的异常处理,就要先明白异常与错误的区别
在Java中,错误和异常是两个不同的概念。
错误分为语法错误、运行时错误和逻辑错误三类。
语法错误(编译错误)
指未按照 Java 语法规则书写代码而产生的错误。一般集成开发软件均能提示和标 注语法错误之处
运行时错误(语义错误)
程序没有语法错误,但在运行时从外部获得不正确的数据从而导致的错误。如将11 位电话号码赋值给一个整型变量将超出其表示的数据范围而引发错误。 这类错误一般会导致程序异常终止。
逻辑错误
逻辑错误是人为导致的错误,表现为程序运行结果与预期不符。如程序的本来意愿 是计算a+b,但疏忽写成了a-b,这类错误一般不会导致程序终止,但显然不可能 得到正确的结果
上述三种错误是程序从开发到调试运行阶段面临的必须处理的问题。但将错误和异常放在一起讨论时,“错误”不是指上述三种中的任何一种。
错误:
一般指程序运行时遇到的硬件或操作系统的错误,如内存溢出、不能读取硬盘分区、 硬件驱动错误等。这是致命的,将导致程序无法运行,同时也是程序本身不能处理的。
异常:
指在运行环境正常的情况下遇到的运行时错误。异常是非致命的,但也会导致程序 的非正常终止。 Java可以捕获和处理异常。
java可以捕获和处理异常
在Java中通常用try-catch-finally捕获并处理异常类,用throw,throws用来抛出异常
当然Java也可以自定义异常
异常的产生:例如下面的代码在运行是将产生异常
package ch09;
public class Demo{
public static void main(String[] args){
int i;
int[] a = {1,2,3,4};
for(i = 0 ; i < 5 ; i++){
System.out.println(" a["+i+"]="+a[i]);
}
System.out.println("5/0="+(5/0));
}
}
运行的结果:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4 at ch09.Demo.main(Demo.java:7)
Exception in thread "main" java.lang.ArithmeticException: / by zero at ch09.Demo.main(Demo.java:8)
使用try-catch-finally捕获和处理异常
语法结构
try{
要检查的语句序列:可能要抛出异常的代码
}catch(异常类名 形参对象名){
异常发生时处理的语句序列
}finally{
无论是否产生异常,都要执行这部分语句
}
package ch09;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Demo{
public static void main(String[] args){
Scanner scn=new Scanner(System.in);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
System.out.println("请输入出生日期(yyyy-MM-dd):");
String strBirth=scn.next();
try {
Date birth=sdf.parse(strBirth);
System.out.println("生日:"+birth);
}catch(ParseException pe) {
System.out.println("生日错误!");
pe.printStackTrace();
}finally {
System.out.println("程序执行finally块!");
}
}
}
代码展示
多异常处理:
类似与switch-case
public class Demo{
public static void main(String[] args){
int i;
int[] a={1,2,3,4};
for(i=0;i<5;i++){
try{
System.out.print("a["+i+"]/"+i+"="+(a[i]/i));
}catch(ArrayIndexOutOfBoundsException e){
System.out.print("捕获到了数组下标越界异常");
}catch(ArithmeticException e){
System.out.print("异常类名称是:"+e);
}catch(Exception e){
System.out.println("捕获"+e.getMessage()+"异常!");
}finally{
System.out.println(" finally i="+i);
}
}
System.out.println("继续!!");
}
}
代码展示
抛出异常
public class Demo{
public static void main(String[] args){
int a=5,b=0;
try{
if(b==0)
throw new ArithmeticException(); //抛出异常
else
System.out.println(a+"/"+b+"="+a/b);
}catch(ArithmeticException e){ //方法内处理异常
System.out.println("异常:"+e+" 被抛出了!");
e.printStackTrace();
}
}
}
代码展示
自定义异常
自定义的异常类一般步骤:
(1) 自定义异常类要继承于Exception类或其子类,或其它异常类。
(2) 为自定义异常类声明字段(属性)成员、方法成员或重写父类的字段和方 法。
(3) 自定义异常类一般要定义两个构造方法:一个是无参的;另外一个是带 String参数的,目的是将此字符串传递给父构造方法,同时这个String的 信息作为该异常对象的描述信息。如果不采取上述方法,则重写toString() 方法。
(4) 最后,起一个能标识异常情况的有意义的名字。
示例一:没有自定义带String参数的构造方法
class CircleException extends Exception{ //自定义的异常类
double radius;
CircleException(double r){
radius = r;
}
public String toString(){
return "半径r="+radius+"不是一个正数";
}
}
class Circle{ //定义Circle类
private double radius;
//方法头确定抛出某种异常
public void setRadius(double r) throws CircleException{
if(r<0) //满足抛出异常的条件则抛出异常
throw new CircleException(r);
else
radius=r;
}
public void show(){
System.out.println("圆面积="+3.14*radius*radius);
}
}
public class Demo{
public static void main(String[] args){
Circle cir=new Circle();
try{
cir.setRadius(-2.0);
}catch(CircleException e){
System.out.println("自定义异常:"+e.toString()+"");
}
cir.show();
} }