异常的处理

异常

  • 异常(Exception)是程序运行过程中发生的事件,该事件可以中断程序指令的正常执行流程。

Java异常分为两大类:

  • 错误(Error)是指JVM系统内部错误,资源耗尽等严重情况;
  • 违例(Exception)则是指其他因编程错误或偶然的外在因素导致的一般性问题,例如对负数开平方根、空指针访问、试图读取不存在的文件以及网络连接中断等。
public class TestException{
	public static void main(String[] args) {
		String friends[]={"Lisa","Bily","Kessy"};
		for(int i=0;i<5;i++)  {
			System.out.println(friends[i]);
		}
		System.out.println("\nthis is the end");
	}
}

 程序运行时错误,输出结果:

Lisa
Bily
Kessy
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:3 at TestException.main(TestException.java:5)
class Person{
	public int age;
}
public class TestNullPointerException{
	public static void main(String[] args) 
	{
		Person p=null;
		System.out.println(p.age);
	}
}
程序运行时出错,输出结果:
Exception in thread "main" java.lang.NullPointerException at TestNullPointerException.main(TestNullPointerException.java:8)

 异常类层次

异常的处理_第1张图片

常见异常

RuntimeException

  • 错误的类型转换
  • 数组下标越界
  • 空指针访问

IOException

  • 从一个不存在的文件中读取数据
  • 超过文件结尾继续读取
  • 连接一个不存在的URL

异常处理机制

Java异常处理的宗旨

  1. 返回到一个安全和已知的状态
  2. 能过使用户执行其他的命令
  3. 如果可能,则保存所有的工作
  4. 如果有必要,可以推出以避免造成进一步危害

处理机制

  1. Java 程序执行过程中如出现异常,系统会监测到并自动生成一个相应的异常类对象,然后再将它交给运行时系统
  2. 运行时系统再寻找相应的代码来处理这一异常,如果java运行时系统找不到可以处理异常的代码,则运行时系统将终止,相应的java程序也将退出
  3. 程序员通常对错误(Error)无能为力,因而一般只处理违例(Exception).
try{
	...//可能产生异常的代码
}catch(ExceptionName1 e){
	...//当产生ExceptionName1型异常时的处置措施
}catch(ExceptionName2 e){
	...//当产生ExceptionName2型异常时的处置措施
}finally{
	...//无条件执行的语句
}
public class Test{
	public static void main(String[] args){
		String friends[]={"Lisa","Billy","Kessy"};
		try{
			for(int i=0;i<5;i++){
				System.out.println(friends[i]);
			}
		}catch(ArrayIndexOutOfBoundsException e){
			System.out.println("index err");
		}
		System.out.println("\n this is--------->end");
	}
}

 输出结果:
Lisa
Bily
Kessy
index err
this is--------->end

使用finally块

public class Test{
	public static void main(String[] args){
		String friends[]={"Lisa","Billy","Kessy"};
		try{
			for(int i=0;i<5;i++){
				System.out.println(friends[i]);
			}
		}catch(ArrayIndexOutOfBoundsException e){
			System.out.println("index err");
			return;
		}finally{
			System.out.println("in finally block");
		}
		System.out.println("\n this is--------->end");
	}
}

输出结果:
Lisa
Bily
Kessy
index err
in finally block

追踪运行栈信息

public class A{
	public void work(int[] a){
		String s = this.contain(a,3);
		System.out.println("Result: " + s);			
	}
	public String contain(int[] source, int dest){
		String result = "no!";
		try{
			for(int i=0;i<source.length;i++){
				if(source[i] == dest)
					result =  "yes!";		
			}
		}catch(Exception e){
			System.out.println("Exception Message: " + e.getMessage());
			System.out.println("Stack Trace:");
			e.printStackTrace();	
			result = "error!";
		}
		return result;
	}
}
public class MyTest{
	public static void main(String[] args)    {
		A tst = new A();
		tst.work(null);
	}
}

 输出结果:
异常信息:null
运行栈信息:
java.lang.NullPointerException at A.contain(A.java:9) at A.work(A.java3) at MyTest.main(Mytest.java:4)
Result:error!

输入/输出异常

import java.io.*;
public class TestIOException{
	public static void main(String[] args)    {
		FileInputStream in=new FileInputStream("myfile.txt");
		int b;
		b = in.read();
		while(b!= -1) {
			System.out.print((char)b);
			b = in.read();
		}
		in.close();
	}
}
TestIOException.java:4: 未报告的异常 java.io.FileNotFoundException;必须对其进行捕捉或声明以便抛出
                FileInputStream in=new FileInputStream("myfile.txt");
                                   ^
TestIOException.java:6: 未报告的异常 java.io.IOException;必须对其进行捕捉或声明以便抛出
                b = in.read();
                           ^
TestIOException.java:9: 未报告的异常 java.io.IOException;必须对其进行捕捉或声明以便抛出
                        b = in.read();
                                   ^
TestIOException.java:11: 未报告的异常 java.io.IOException;必须对其进行捕捉或声明以便抛出
                in.close();
                        ^
4 错误 
import java.io.*;
public class TestIOException{
	public static void main(String[] args) {
		try{
			FileInputStream in=new FileInputStream("myfile.txt");
			int b;
			b = in.read();
			while(b!= -1) {
				System.out.print((char)b);
				b = in.read();
			}
			in.close();
		}catch(FileNotFoundException e){
			System.out.println("File is missing!");
		}catch(IOException e){
			e.printStackTrace();	
		}
		System.out.println("It's ok!");
	}
}

声明抛弃异常

声明抛弃异常时java中处理违例的第二种方式,如果一个方法中的代码在运行时可能生成某种异常,但在本方法中不必,或者不能确定如何处理异常时,则可以声明抛弃改异常,此时方法中将不对此类异常进行处理,而是由该方法的调用负责处理。

[<修饰符>]<返回值类型><方法名>(<参数列表>)[throws<异常类型>[,<异常类型>]*]{
 [<Java语句>]*
}

import java.io.*;
public class TestThrowsException{
	public static void main(String[] args){
		TestThrowsException t = new TestThrowsException();
		try{
		 	t.readFile();
		 }catch(IOException e){
		 	System.out.println(e); 
		 }
	}
	public void readFile()throws IOException {
		FileInputStream in=new FileInputStream("myfile.txt");
		int b;	
		b = in.read();
		while(b!= -1)   {
			System.out.print((char)b);
			b = in.read();
		}
		in.close();	
	}
}

 重写方法声明抛弃异常

重写方法不允许抛出比被重写方法范围更大的异常类型:

public class A{
	public void ma() throws IOException{
	...
	}
}
public class B1 extends A{
	public void ma() throws FileNotFoundException,EOFExceotion{
	...
	}
}
public class B2 extends A{
	public void ma() throws Exception{//非法
	...
	}
}

 人工抛出异常

  • Java异常类对象除了在程序运行出错时由系统自动生出抛出之外,也可根据需要人工创建并抛出
IOException e=new IOException();
throw e;

 

  • 被抛出的必须是Throwable或其子类类型的对象,下述语句在编译时会产生语法错误
throw new String("want to throw");

用户自定义异常

java语言针对常见异常状况已事先定义了相应的异常类型,并在程序运行出错时由系统自动创建相应异常对象并进行抛出,捕获和处理,因此一般不需要用户人工抛出异常对象或定义新的异常类型,针对特殊的需要也可以这样做

public class MyException extends Exception {
   	private int idnumber;
 	public MyException(String message, int id) {
		super(message);
		this.idnumber = id;
 	} 
	public int getId() {
		return idnumber;
 	}
}
public class TestCustomizingException{
	public void regist(int num) throws MyException {
		if (num < 0) {
			throw new MyException("人数为负值,不合理",3);
		}
		System.out.println("登记人数:" + num );
	}
	
	public void manager() {
		try {
			regist(-100);
		} catch (MyException e) {
			System.out.println("登记失败,出错种类"+e.getId());	
		}
		System.out.print("本次登记操作结束");
	}
	
	public static void main(String args[]){
		new TestCustomizingException().manager();
	}
}

输出结果:

登记失败,出错种类3

本次登记操作结束

断言(Assert)

从JDK1.4版本开始,java语言中引入了断言(Assert)机制——允许java开发者在代码中加入一些检查语句,主要用于程序调试目的:

  • 断言机制在用户定义的boolean表达式(判断条件)结果为false时抛出一个Error对象,其类型为AssertionError;
  • 当我们需要在约定的条件不成立时中断当前操作的话,可以使用断言
  • 作为Error的一种,断言失败也不需要捕获处理或者声明抛出,一旦出现了则终止程序、不必进行补救和恢复。

启用和禁用断言

开启断言功能:

Java运行时环境默认设置为关闭断言功能,因此在使用断言以前,需要在运行Java程序时先开启断言

java-ea MyAppClass //或者
java-enableassertions MyAppClass

关闭断言功能:

java-da MyAppClass //或者
java-disableassertions MyAppClass

assert<boolean表达式>;

public class TestAssertion{
	public static void main(String[] args){
		new TestAssertion().process(-12);
	}
	
	public void process(int age){
		assert age>=0;
		System.out.println("您的年龄:" + age);
		//---	
	}	
}
启用断言时输出结果:(使用命令"java-ea TestAssertion"运行程序)
Exception in thread "main" java.lang.AssertionError
        at TestAssertion.process(TestAssertion.java:7)
        at TestAssertion.main(TestAssertion.java:3)

关闭断言时输出结果:(使用命令"java TestAssertion" 运行程序)
您的年龄:-12

 assert<boolean表达式>:<表达式2>;

public class TestAssertion2{
	public static void main(String[] args){
		new TestAssertion2().process(-12);
	}
	
	public void process(int age){
		assert age>=0:"年龄超出合理范围!";
		System.out.println("您的年龄:" + age);
		//---	
	}	
}
启用断言时输出结果:
Exception in thread "main" java.lang.AssertionError: 年龄超出合理范围!
        at TestAssertion2.process(TestAssertion2.java:7)
        at TestAssertion2.main(TestAssertion2.java:3)

关闭断言时输出结果:
您的年龄:-12

 

你可能感兴趣的:(java,jvm,thread,编程)