异常处理
1.异常概述
异常的类型:Error(致命的),Exception(非致命的)以及必检和免检异常。
异常就是一种对象,表示阻止正常进行程序执行的错误或者情况。
异常是从方法中抛出的。方法的调用者可以捕获以及处理该异常。
一个简单的例子:
package exception;
import java.util.Scanner;
public class QuotientWithIf {
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.println(“输入两个数:”);
int num1 = input.nextInt();
int num2 = input.nextInt();
System.out.println(num1 + “/” + num2 + “ is “ + (num1/num2));
}
}
结果:
出现了异常错误,除数不能为零。
修改如下:
package exception;
import java.util.Scanner;
public class QuotientWithIf {
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.println(“输入两个数:”);
int num1 = input.nextInt();
int num2 = input.nextInt();
if(num2!= 0) {
System.out.println(num1 + “/” + num2 + “ is “ + (num1/num2));
}
System.out.println(“除数不能为零”);
}
}
结果:
但是仍然存在问题,不应该让方法来终止程序,应该由调用者决定是否终止程序。也就是尽量不使用main方法终止,main方法只调用。如下:
package exception;
import java.util.Scanner;
public class QuotientWithIf {
public static int quotient(int num1 ,int num2) {
if(num2==0) {
System.out.println(“除数不能为零”);
System.exit(1);
}
return num1/num2;
}
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.println(“输入两个数:”);
int num1 = input.nextInt();
int num2 = input.nextInt();
int result = quotient(num1,num2);
System.out.println(num1 + “/” + num2 + “ is “ + result);
}
}
结果:
这种防止异常的方法由人为的判断,调用对象无法得知是否发生异常
Java可以让一个方法抛出一个异常,该异常可以被调用者捕获和处理。
如下:
package exception;
import java.util.Scanner;
public class QuotientWithIf {
public static int quotient(int num1 ,int num2) {
if(num2==0) {
throw new ArithmeticException(“除数不能为零”);
}
return num1/num2;
}
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.println("输入两个数:");
int num1 = input.nextInt();
int num2 = input.nextInt();
try {
int result = quotient(num1,num2);
System.out.println(num1 + "/" + num2 + " is " + result);
}
catch(ArithmeticException ex){
System.out.println("除数不能为零");
}
}
}
结果:
上面代码中的 throw new ArithmeticException();
throw语句的执行就是抛出一个异常。异常就是一个从异常类中创建的对象。
当异常被抛出的时候,正常的执行流程就被打断。抛出异常就是将异常从一个地方传递到另一个地方。
throw 语句类似方法的调用,但不同调用方法的是,它调用的是catch块,从某种意义上讲,catch就像带参数的方法定义,这些参数匹配抛出的值 的类型。但是,不像方法,在执行完catch快之后,程序控制不返回到throw语句,而是执行到catch块后的下一条语句。
使用异常处理的优点:
使方法抛出一个异常给它的调用者,并由调用者处理该异常。如果没有该能力,那么被调用的方法就必须自己处理异常或者终止该程序。被调用的方法在不知道出错的情况下该做什么,这是库方法的一般情况。库方法可以检查除错误,但是只有调用者才知道出现错误时需要做些什么。异常处理最根本的优势就是将检测错误从处理错误中分离出来。
很多库方法都会抛出异常,一个简单的例子。
package exception;
import java.util.InputMismatchException;
import java.util.Scanner;
public class InputException {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean continueInput = true;
do {
try {
System.out.println(“Enter an integer number:”);
int number =input.nextInt();
System.out.println(“The integer number is” + number);
continueInput = false;
}
catch(InputMismatchException ex) {
System.out.println("Try again.(Incorrect input: an integer is required");
input.nextLine();
}
}
while(continueInput);
}
}
结果:
Enter an integer number:
5.5
Try again.(Incorrect input: an integer is required
Enter an integer number:
5
The integer number is5
2.异常类型
异常是对象,而对象的采用都是用类来定义。异常的根类是java.lang.Throwable.
Throwable:
系统错误(error)是由虚拟机抛出的,用error类表示。Error类描述的是内部系统错误,很少发生。如果发生除了通知用户以及尽量稳妥的终止程序,几乎什么都不能做。
异常(Exception)使用Exception类来表示,它描述的是程序和外部环境所引起的错误,这些错误能够被捕获和处理
运行时异常(runtime exception)是用RuntimeException类表示的,它描述的是程序设计错误,例如,错误的类型转换,访问一个越界数组或者数值错误,运行时异常通常是由Java虚拟机抛出的。
3.异常的三种操作
(1)声明异常
在Java中当前执行的语句一定属于某个方法,Java解释器调用mian方法开始执行一个程序。每个方法都必须声明它可能抛出的必检异常的类型。
任何代码都可能发生系统错误和运行时错误,因此,Java不要求在方法中显示声明Error和RuntimeException,但是方法抛出的其他异常都必须在方法头中显示声明,这样方法的调用者会被告知有异常
如:
public void myMethod() throws IOException{}
关键字throws表明myMethod方法可能会抛出异常
(2)抛出异常
检测到错误的程序可以创建一个合适的异常类型的实例并抛出它。
如
IllegalArgumentException ex = new IllegalArgumentException(“Wrong Argument”);
throws ex;
注意,声明异常的关键字是throws ,抛出异常的关键字是throw
(3)异常 的捕获
当抛出一个异常时,可以在try-catch块中捕获异常
如:
try{
satatements;
}
catch(Exception exVar1{
handle foe Ecception;
}
4.从异常中获取信息
上个图为虚拟机里的Trrowable类库方法。
package exception;
public class TestException {
private static int sum(int [] list) {
int result = 0;
for(int i=0;i<list.length;i++) {
result +=list[i];
}
return result;
}
public static void main(String[] args) {
try {
System.out.println(sum(new int[]{1,2,3,4,5}));
}
catch(Exception ex) {
ex.printStackTrace();
System.out.println("\n" + ex.getMessage());
System.out.println("\n" + ex.toString());
System.out.println("\nTrace InfoObtained from getStackTrace");
StackTraceElement[] traceElements = ex.getStackTrace();
for(int i=0;i<traceElements.length;i++) {
System.out.println("method" + traceElements[i].getMethodName());
System.out.println("(" + traceElements[i].getClassName() + ":");
System.out.println(traceElements[i].getLineNumber() + ")");
}
}
}
}
结果:
一个声明,抛出和不捕获异常的例子
package exception;
public class CircleWithException {
private double radius;
private static int numberOfObjects =0;
public double getRadius() {
return radius;
}
public void setRadius(double newradius)throws IllegalArgumentException {
if(newradius>=0) {
radius = newradius;
}
else {
throw new IllegalArgumentException("Radius cannot be negative");
}
}
public static int getNumberOfObjects() {
return numberOfObjects;
}
public CircleWithException() {
this(1.0);
}
public CircleWithException(double newRadius) {
// TODO Auto-generated constructor stub
setRadius(newRadius);
numberOfObjects++;
}
public double findArea() {
return radius * radius* 3.14159;
}
}
package exception;
public class TestCircleWithException {
public static void main(String [] args) {
try {
CircleWithException c1 =new CircleWithException(5);
CircleWithException c2 =new CircleWithException(-5);
CircleWithException c3 =new CircleWithException(0);
}
catch(IllegalArgumentException ex) {
System.out.println(ex);
}
System.out.println("Number of objects created:" + CircleWithException.getNumberOfObjects());
}
}
结果:
5.finally子句
无论异常是否发生,finally子句都会被执行。
有时候,不论异常是否出现或者是否被捕获,都希望执行某些代码。所以用finally子句来达到这个目的。语法如下:
try{
statements;
}
catch(TheException ex){
handing ex;
}
finally{
finallyStatements;
}
注意事项:
***在使用try-catch块时,当处理不可预料处理 的错误状况时应该使用它。不要用try-catch块处理简单的,可预料的情况。***比如:
try{
System.out.println(refVar.toString());
}
catch(NullPointerException ex){
System.out.println(“refVar id null”);
}
应该用如下代码替换:
if(refVar ! =null)
System.out.println(refVar.toString());
else
System.out.println(“refVar id null”);
还没有评论,来说两句吧...