java基础:8.1 异常
发布日期:2022-04-04 06:36:30 浏览次数:17 分类:博客文章

本文共 4957 字,大约阅读时间需要 16 分钟。

 

异常的根类是 java.lang.Throwable
异常处理的优点:它能使方法抛出一个异常给它的调用者,由调用者处理该异常。
key word : try、 catch 、 finally、 throws
 

1. 一般形式

throw new ArithmeticException(“XXX”);

// java.lang.ArithmeticException,在方法中使用。当异常被抛出,正常的执行流程被中断

try { 正常代码 }

catch( 异常类型 ) { 处理或者抛出异常 } 可以存在多个catch块,或者使用 | 在一个块内声明

finally { 此处的语一定会被执行 }

注意,不要用try-case块处理简单、可预料的情况!!!

 

2. finally

在任何情况下,finally块中的代码都会被执行,不论try块中是否出现异常或者是否被捕获。考虑下面三种可能出现的情况:

如果try块中没有出现异常,执行finalStatements,然后执行try语句的下一条语句。

如果try块中有一条语句引起异常,并被catch捕获,然后跳过try块的其他语句,执行catch块和finally子句。执行try语句之后的下一条语句。
如果try块中有一条语句引起异常,但是没有被任何catch块捕获,就会跳过try块中的其他语句,执行finally子句,并且将异常传递给这个方法的调用者。
即使在到达finally块之前有一个return语句,finally块还是会执行。
 

3.throw 和 throws

throws与throw这两个关键字接近,不过意义不一样,有如下区别:

  • throws 出现在方法声明上,而throw通常都出现在方法体内。
  • throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。
     

4. 异常分类

所有的java异常类都直接或者间接地继承自Throwable。可以通过继承Exception或者Exception的子类来创建自己的异常类。

异常类有三种主要类型:

异常 (Exception) 又叫可查异常: CheckedException,是必须进行处理的异常,要么try catch,要么往外抛,谁调用,谁处理,如果不处理,编译器就不让你通过。

系统错误/Error (System Error)是由java虚拟机抛出的,用Error类表示,不要求强制捕获

Error类描述的是内部系统错误,这样的错误很少发生。如果发生,除了通知用户以及尽量稳妥地终止程序外,几乎什么也不能做。常见的有:内存用光了,抛出OutOfMemoryError
 
运行时异常 (Runtime Exception)是用RuntimeException类表示的,它描述的是程序设计错误, 不是必须进行try catch。在编写代码的时候,依然可以使用try catch throws进行处理,与可查异常不同之处在于,即便不进行try catch,也不会有编译错误。运行时异常通常是由Java 虚拟机抛出的。

Exception这个层次结构又分解为连个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException;而程序本身没有没有问题,但由于像I/O错误这类异常导致的异常属于其他异常。

常见的RuntimeException(运行时异常):

IndexOutOfBoundsException(下标越界异常)

NullPointerException(空指针异常)
NumberFormatException (String转换为指定的数字类型异常)
ArithmeticException -(算术运算异常 如除数为0)
ArrayStoreException - (向数组中存放与声明类型不兼容对象异常)
SecurityException -(安全异常)
IOException(其他异常)
FileNotFoundException(文件未找到异常。)
IOException(操作输入流和输出流时可能出现的异常。)
EOFException (文件已结束异常)

 

5. 自定义异常

我们可以创造一个类,继承某个自定义的异常。

public class DefineException extends Exception{
}

如果方法没有在父类中声明异常,那么就不能再子类中对其进行继承来声明异常。

在catch块中异常被指定的顺序是非常重要的,如果父类的catch块出现在唉子类的catch块之前,就会导致编译错误。

 
 

修改我们之前的类Circle

// Circle.javapublic class Circle {    private double radius;    private static int circleNumber =0;        /*	set radius */    Circle(){        circleNumber++;        radius = 1.0;    }    Circle(double newRadius){        setRadius(newRadius);        circleNumber++;    }    /* return radius */    public double getRadius() {    	return radius;    }    /* set radius     public void setRadius(double radius) {	    	this.radius = (radius >=0) ? radius : 0;    } */       public void setRadius(double radius) throws IllegalArgumentException{	/* 即使在方法声明中删除throws IllegalArgumentException 子句,Circle类也仍然会编译,因为该异常是RuntimeException 的子类,而且不管是否在方法头中声明,每个方法都能抛出RuntimeException 异常(免检异常)。*/    	if (radius>=0)      		this.radius=radius;    	else throw new IllegalArgumentException("radius cannot be negative");    }     /* get the number of all circles */    public static int getNumberOfCircle() {    	return circleNumber;    }    public double getArea(){        return radius*radius*Math.PI;    }}

测试程序

//  testCircle.javapublic class testCircle {	public static void main(String[] args) {		// TODO Auto-generated method stub		try {		Circle c1 = new Circle(-2);		Circle c2 = new Circle(5);		Circle c3 = new Circle();		Circle c4 = new Circle(0);		}		catch (IllegalArgumentException ex) {			System.out.println(ex);		}		System.out.println("the number of circle is : " + Circle.getNumberOfCircle());	}}

观察程序的运行结果,我们发现:当c1出现异常,成功catch后,不会再返回执行Circle c2 = new Circle(5)以及后续语句;程序会顺着catch块后继续执行。

basic knowledge:

在执行完catch 块之后,程序控制不返回到throw 语句;而是执行catch 块后的下一条语句
 

自定义异常代码

//  DefineException.javapublic class DefineException extends Exception {	private double radius;	public DefineException(double radius) {		super("Invaild radius "+radius);		this.radius= radius;	}	public double getRadius() {		return radius;	}}// Circle.javapublic class Circle {    private double radius;    private static int circleNumber =0;        /*	set radius */    Circle() throws DefineException {        circleNumber++;        radius = 1.0;    }    Circle(double newRadius) throws DefineException{        setRadius(newRadius);        circleNumber++;    }    /* return radius */    public double getRadius() {    	return radius;    }    public void setRadius(double radius) throws DefineException{	    	if (radius>=0)      		this.radius=radius;    	else throw new DefineException(radius);    }        /* get the number of all circles */    public static int getNumberOfCircle() {    	return circleNumber;    }        public double getArea(){        return radius*radius*Math.PI;    }}
//  testCircle.javapublic class testCircle {	public static void main(String[] args) {		// TODO Auto-generated method stub		try {		Circle c1 = new Circle(-2);		Circle c2 = new Circle(5);		Circle c3 = new Circle(6);		Circle c4 = new Circle(0);		}		catch (DefineException ex) {			System.out.println(ex);		}		finally {			System.out.println("finally");		}		System.out.println("the number of circle is : " + Circle.getNumberOfCircle());	}}

转载地址:https://www.cnblogs.com/l20902/p/10610889.html 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java基础:8.2 异常 编程练习
下一篇:java基础:6.4 日期类、日历类

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年03月22日 23时12分18秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章