龙空技术网

关于Java Exception异常的深入用法及实例

心有花宇龙传人 319

前言:

眼前大家对“java进程假死”都比较关怀,同学们都需要剖析一些“java进程假死”的相关内容。那么小编也在网上收集了一些关于“java进程假死””的相关资讯,希望同学们能喜欢,朋友们快快来了解一下吧!

关于Java Exception异常的深入用法及实例一、异常的概念

生活中的异常:例如感冒发烧,工作时电脑蓝屏、死机等。

程序中的异常:在程序运行的过程中,也会发生这种非正常状况,例如程序运行时磁盘空间不足、网络连接中断、被加载的类不存在等。

程序异常解决方法:针对程序中的非正常情况,Java语言中引入了异常,以异常类的形式对这些非正常情况进行封装,并通过异常处理机制对程序运行时发生的各种问题进行处理。

示例:

public static int divide(int x,int y)

{

int result = x/y;

return result;

}

int result = divide(4, 0);

System.out.println(result);

产生了ArithmeticException异常,这个异常只是Java异常类中的一种,在Java中还提供了大量的异常类,这些类都继承自java.lang.Throwable类。

1.1Throwable异常体系结构

Exception称为异常类,它表示程序本身可以处理的错误。在Java程序开发中进行的异常处理,都是针对Exception类及其子类的。

Error称为错误,表示Java运行时产生的系统内部错误或资源耗尽的错误,是比较严重的,仅靠修改程序本身是不能恢复执行的,例如系统崩溃,虚拟机错误等。

Exception分类:在Exception类的众多子类中有一个特殊的RuntimeException类,该类及其子类用于表示运行时异常。除了此类,Exception类下所有其他的子类都用于表示编译时异常。

Throwable类中的常用方法

二、异常的类型

1、编译时异常

在程序编译时期产生的异常,而这些异常必须要进行处理,也称为checked异常。

2、运行时异常

这种异常即使不编写异常处理代码,依然可以通过编译,也称为unchecked异常。

2.1编译时异常

异常类汇总:在Exception的子类中,除了RuntimeException类及其子类外,其他子类都是编译时异常。

特点:编译时异常的特点是在程序编写过程中,Java编译器就会对编写的代码进行检查,如果出现比较明显的异常就必须对异常进行处理,否则程序无法通过编译。

2.1.1编译时异常示例

public static void main(String[] args)

{

int i,j;

System.out.println("i="+i+",j="+j);

}

编译时报错,通过不了,未附初始值。

2.1.2处理编译时异常方式

使用try...catch语句对异常进行捕获处理;

使用throws关键字声明抛出异常,让调用者处理。

2.2运行时异常

异常汇总:RuntimeException类及其子类都是运行时异常。

特点:运行时异常是在程序运行时由Java虚拟机自动进行捕获处理的,即使没有使用try..catch语句捕获或使用throws关键字声明抛出,程序也能编译通过,只是在运行过程中可能报错。

2.2.1运行时异常-常见的运行时异常

运行时异常错误分析:运行时异常一般是由于程序中的逻辑错误引起的,在程序运行时无法恢复。

int[] arr = new int[5];

System.out.println(arr[5]);

三、try...catch和finally

当程序发生异常时,会立即终止,无法继续向下执行。为了保证程序能够有效的执行,Java中提供了一种对异常进行处理的方式——异常捕获。

异常捕获try…catch语句的基本语法格式:

try {

// 可能发生异常的语句

} catch(Exception类或其子类 e){

// 对捕获的异常进行相应处理

}

上述代码中,try{}代码块中包含的是可能发生异常的语句,catch(){}代码块中编写针对捕获的异常进行处理的代码。当try{}代码块中的程序发生了异常,系统会将这个异常的信息封装成一个异常对象,并将这个对象传递给catch(){}代码块。catch(){}代码块需要一个参数指明它所能够接收的异常类型,这个参数的类型必须是Exception类或其子类。

3.1try...catch示例

public static int divide(int x,int y) {

try{

int result = x/y;

return result;

} catch(Exception e) {

System.out.println("捕获的异常信息为:" + e.getMessage());

}

return -1;

}

int result = divide(4, 0);

if(result==-1){

System.out.println("程序发生异常!");

}else{

System.out.println(result);

}

示例中,对运算方法divide()中可能发生异常的代码用try...catch语句进行了捕获处理。在try{}代码块中发生被0除异常,程序会转而执行catch(){}中的代码,通过调用Exception对象的getMessage()方法,即可返回异常信息”/ by zero”。

catch(){}代码块对异常处理完毕后,程序仍会向下执行,而不会因为异常而终止运行。

需要注意的是,在try{}代码块中,发生异常语句后面的代码是不会被执行的,return result就没有被执行。

3.2finally示例

在程序中,希望有些语句无论程序是否发生异常都要执行,这时就可以在try...catch语句后,加一个finally{}代码块。对上一个示例进行修改,演示finally{}代码块的用法。

public static int divide(int x,int y) {

try{

int result = x/y;

return result;

} catch(Exception e) {

System.out.println("捕获的异常信息为:" + e.getMessage());

} finally {

System.out.println("执行finally代码块,无论程序是否异常,都会执行");

}

return -1;

}

int result = divide(4, 0);

if(result==-1){

System.out.println("程序发生异常!");

}else{

System.out.println(result);

}

例中divide()方法中增加了一个finally{}代码块,用于处理无论程序是否发生异常都要执行的语句,该代码块并不受return语句和程序异常的影响。由于这种特殊性,在程序设计时,经常会在try...catch后使用finally{}代码块来完成必须做的事情,例如释放系统资源、关闭线程池等。

finally中的代码在一种情况下是不会执行的,那就是在try...catch中执行了System.exit(0)语句。

System.exit(0)表示退出当前的Java虚拟机,Java虚拟机停止了,任何代码都不能再执行了。

四、throws关键字

如果不确定或者并不急于处理异常,怎么办?

一般在程序开发中,开发者通常会意识到程序可能出现的问题,可以直接通过try...catch对异常进行捕获处理。但有些时候,方法中代码是否会出现异常,开发者并不明确或者并不急于处理,为此,Java允许将这种异常从当前方法中抛出,然后让后续的调用者在使用时再进行异常处理。

throws关键字抛出异常的基本语法格式:

[修饰符] 返回值类型 方法名([参数类型 参数名1...]) throws 异常类1,异常类2,... {

// 方法体...

}

throws关键字需要写在方法声明的后面,并在后面需要声明方法中发生异常的类型。

注意:当调用者在调用有抛出异常的方法时,除了可以在调用程序中直接进行try…catch异常处理外,也可以根据提示使用throws关键字继续将异常抛出,这样程序也能编译通过。但是,程序发生了异常,终究是需要进行处理的,如果没有被处理,程序就会非正常终止。

示例1,单纯声明抛出异常

public static int divide(int x,int y) throws Exception{

int result = x/y;

return result;

}

public static void main(String[] args)

{

int result = divide(4, 0);

System.out.println(result);

}

抛出的异常主程序未捕获,编译通不过:

示例2,使用try...catch对异常捕获处理:

public static int divide(int x,int y) throws Exception{

int result = x/y;

return result;

}

public static void main(String[] args)

{

try{

int result = divide(4, 0);

System.out.println(result);

} catch(Exception e)

{

System.out.println("捕获的异常信息为:"+e.getMessage());

}

}

try...catch{}捕获住了异常信息,运行结果:

示例3,继续使用throws关键字将异常抛出

public static int divide(int x,int y) throws Exception{

int result = x/y;

return result;

}

public static void main(String[] args) throws Exception

{

int result = divide(4, 0);

System.out.println(result);

}

主程序中,将异常信息抛出,打印,程序非正常终止:

五、throw关键字

程序开发中,除了可以通过throws关键字抛出异常外,还可以使用throw关键字抛出异常。

throw关键字:throw关键字用于方法体内,并且抛出的是一个异常类对象。

throws关键字:throws关键字用在方法声明中,用来指明方法可能抛出的多个异常。

说明:通过throw关键字抛出异常后,还需要使用throws关键字或try…catch对异常进行处理。

注意:如果throw抛出的是Error、RuntimeException或它们的子类异常对象,则无需使用throws关键字或try…catch对异常进行处理。

throw关键字抛出异常的基本语法格式:

[修饰符] 返回值类型 方法名([参数类型 参数名,...]) throws 抛出的异常类 {

// 方法体...

throw new Exception类或其子类构造方法;

}

示例:

public static void printAge(int age) throws Exception{

if(age<=0){

throw new Exception("输入的年龄有误,必须是正整数!");

}else{

System.out.println("此人年龄为:"+age);

}

}

public static void main(String[] args)

{

int age=-1;

try{

printAge(age);

} catch(Exception e)

{

System.out.println("捕获的异常信息为:"+e.getMessage());

}

}

通过在方法中throw抛出异常,主程序捕获异常,可以显示输出结果,后面还可以抛出自定义异常信息。

运行结果:

六、自定义异常

Java中定义了大量的异常类,虽然这些异常类可以描述编程时出现的大部分异常情况,但是在程序开发中有时可能需要描述程序中特有的异常情况,例如在设计divide()方法时不允许被除数为负数。

解决方法:Java允许用户自定义异常,但自定义的异常类必须继承自Exception或其子类。

6.1 定义自定义异常

自定义异常的创建示例:

public class DivideByMinusException extends Exception{

public DivideByMinusException (){

super(); // 调用Exception无参的构造方法

}

public DivideByMinusException (String message){

super(message); // 调用Exception有参的构造方法

}

}

6.2捕获自定义异常

借用前面的自定义异常,捕获示例如下:

public static int divide(int x,int y) throws DivideByMinusException {

if(y==0)

{

throw new DivideByMinusException("除数是0");

}

int result = x/y;

return result;

}

public static void main(String[] args) throws Exception

{

try{

int result = divide(4, 0);

System.out.println(result);

} catch(DivideByMinusException e){

System.out.println("捕获的异常信息为:"+e.getMessage());

}

}

运行结果:

divide()方法通过逻辑判断对除法运算的除数是否为0进行了判断,如果除数为0就使用throw关键字抛出自定义的DivideByMinusException异常对象,然后通过throws关键字抛出异常,并在最后通过try...catch语句捕获异常。

运行结果,程序执行后判断出除数为0,抛出了指定的异常信息。

七、附加示例

示例1:

import java.io.IOError;

/**

* 抛出ERROR类型的异常,不能被程序捕获

* @author 40920

*

*/

public class Demo1 {

public static void main(String[] args)

{

try {

throw new IOError(new Exception("抛出IO异常"));

} catch(Exception e)

{

System.out.println("捕获异常");

}

}

}

示例二:

import java.io.IOError;

/**

* 抛出Exception类型的异常,可以被程序捕获

* @author 40920

*

*/

public class Demo2 {

public static void main(String[] args) {

// TODO Auto-generated method stub

try {

throw new Exception("抛出IO异常");

} catch(Exception e)

{

System.out.println("捕获异常");

}

}

}

示例三:

import java.util.Scanner;

/**

* 输入连续字符串,进行转换

* @author 40920

*

*/

public class Demo3 {

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner scanner = new Scanner(System.in);

String str = null;

System.out.println("请输入字符串,以回车键进入下一行,输入0换行表示程序正常结束");

while(!"0".equals(str=scanner.next()))// 输入不等于0,循环正常

{

Integer num = Integer.parseInt(str);

System.out.println("正常数字:"+num);

}

System.out.println("程序正常结束");

}

}

示例四:

import java.util.Scanner;

/**

* 输入连续字符串,进行转换

* @author 40920

*

*/

public class Demo4 {

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner scanner = new Scanner(System.in);

String str = null;

System.out.println("请输入字符串,以回车键进入下一行,输入0换行表示程序正常结束");

try {

while(!"0".equals(str=scanner.next()))// 输入不等于0,循环正常

{

Integer num = Integer.parseInt(str);

System.out.println("正常数字:"+num);

}

} catch(Exception e)

{

System.out.println("成功捕获异常:"+e.getMessage());

str = null; // 捕获异常后,令str = null

}

if(str!=null)

{

System.out.println("程序正常结束");

} else

{

System.out.println("程序由捕获异常结束");

}

}

}

示例五:

import java.util.Scanner;

public class Demo5 {

public static void main(String[] args) {

// TODO Auto-generated method stub

int[] a = new int[5]; // 初始化数组

int i=0, recvNum; // 定义循环变量,接收输入参数

int result = 0; // 结果和

Scanner scanner = new Scanner(System.in);

try {

while(i<6) // 开启循环

{

System.out.print("请输入整数,以0结束:");

if((recvNum=scanner.nextInt())!=0) // 收到的整数不为0

{

a[i] = recvNum;

result += a[i];

} else

{

break; // 整数为0跳出循环

}

i++; // 循环自增

}

System.out.println("程序正常结束");

} catch(Exception e)

{

System.out.println("程序出现异常退出:"+e.toString());

} finally

{

/**

* 不管怎么样,都执行,不管程序异常、正常与否

*/

System.out.println("计算结果和为:"+result);

}

}

}

示例6:

import java.util.Scanner;

public class Demo6 {

/**

* 计算整除结果,当y=0时整除会抛出异常

* @param x

* @param y

* @return

* @throws Exception

*/

public static int getCalulateResult(int x, int y) throws Exception

{

int sum = 0;

try {

sum = x/y;

} catch(Exception e)

{

System.out.println("出现异常");

throw new RuntimeException(e);

} finally

{

System.out.println("完成方法程序"); // 不管程序如何,都会执行这句话

}

return sum;

}

public static void main(String[] args) throws Exception {

// TODO Auto-generated method stub

int x=0,y=0,sum=0;

int i;

Scanner scanner = new Scanner(System.in);

System.out.print("请输入整数,以-1结束:");

while((i=scanner.nextInt())!=-1)

{

x = i;

/*

* 换行

*/

System.out.println("");

System.out.print("请输入整数,以-1结束:");

if((i=scanner.nextInt())!=-1)

{

y=i;

}

sum = sum + getCalulateResult(x,y);

/*

* 换行

*/

System.out.println("");

System.out.print("请输入整数,以-1结束:");

}

System.out.println("整除结果和为:"+sum);

}

}

示例七:

import com.opendi.generator.exception.demo.vo.CustomException;

public class Demo7 {

/**

* 计算除数

* @param args

*/

public static int divid(int x, int y) throws CustomException

{

int sum = 0;

try {

sum = x/y;

} catch(Exception e)

{

throw new CustomException(e);

}

return sum;

}

/**

* 返回年龄

* @param age

* @return

* @throws CustomException

*/

public static int getAge(int age) throws CustomException

{

if(age<0)

{

throw new CustomException("年龄不得小于0,age:"+age);

}

return age;

}

public static void main(String[] args) {

// TODO Auto-generated method stub

int x,y,age;

x=3;y=1;

try {

int result = divid(x,y);

System.out.println("结果:"+result);

} catch(CustomException e)

{

System.out.println("捕获自定义异常:"+e);

} catch(Exception e1)

{

System.out.println("捕获通用异常:"+e1);

}

x=3;y=0;

try {

int result = divid(x,y);

System.out.println("结果:"+result);

} catch(CustomException e)

{

System.out.println("捕获自定义异常:"+e);

} catch(Exception e1)

{

System.out.println("捕获通用异常:"+e1);

}

age=-2;

try {

age = getAge(age);

System.out.println("年龄:"+age);

} catch(CustomException e)

{

System.out.println("捕获自定义异常:"+e);

} catch(Exception e1)

{

System.out.println("捕获通用异常:"+e1);

}

}

}

/**

* 自定义异常

* @author 40920

*

*/

public class CustomException extends Exception {

public CustomException() {

super();

}

public CustomException(String message) {

super("自定义异常:"+message);

}

public CustomException(Throwable cause) {

super(cause);

}

}

标签: #java进程假死