Java的异常处理机制

<span style="font-family:Times New Roman;font-size:18px;">package com.exception.test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Date;

/*
 * Java的异常处理机制可以让程序具有极好的兼容性,让程序更加健壮
 * 不管程序代码是否处于try语句块中,甚至包括catch块中的代码,只要执行改代码块时出现了
 * 异常,系统总会自动生成一个异常对象。如果程序没有为这段代码定义任何的catch块,则Java运行时环境
 * 无法找到处理该异常的catch块,程序就在此退出。
 * 
 * try{
 * 		statement1
 * 		statement2-----出现异常,系统生成异常对象ex
 * 		....
 * }
 * catch(ExceptionClass1 e1){<---ex instanceof ExeceptionClass1==true
 * 		exception hander statement1
 * 		....
 * }
 * catch(ExceptionClass2 e2){<---ex instanceof ExeceptionClass1==true 
 *		exception handler statement1
 *		....
 * }
 * 
 * Error错误,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,动态链接失败等,该错误无法
 * 恢复或者不可能捕获,通常应用程序无法处理这些错误,因此程序不应该试图使用catch块来捕获Error对象
 * 
 * 
 * 进行异常捕获时,应该把Exception类对应的catch块放在最后,而且所有父类异常的
 * catch块都应该排在子类的异常catch的后面,即先处理小异常,在处理大异常
 * try{
 * 		statements...
 * }
 * catch(NullPointerException e)
 * {
 * 		System.out.println("空指针异常");
 * }
 * catch(RuntimeException e)
 * {
 * 		System.out.println("运行时异常");
 * }
 *
 *
 *虽有的异常对象都包含了如下几个常用方法:
 *getMessage():返回该异常的详细字符描述串
 *printStackTrace():将该异常的跟踪栈信息信息输出到标准错误输出
 *printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定输出流
 *getStackTrace():返回该异常的跟踪栈信息
 *
 *Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只能回收堆内存中对象所占用的内存
 *为了保证一定能回收try块中打开的物理资源,异常处理机制提供了finally块。不管try块中的
 *代码是否出现异常,也不管哪一个catch块被执行,甚至在try或者catch块中执行了return语句,
 *finally块总会被执行。
 *PS:除非在try,catch块中调用了退出虚拟机的方法,否则不管在try块,catch块中执行怎样的代码
 *出现怎样地情况,异常处理的finally块总会被执行。
 *
 *通常情况下,不要在finally块中使用如return或throw等导致方法终止的语句,一旦在finally块中
 *使用了return或throw语句,将会导致try块,catch块中的return,throw语句失效
 */
class AuctionException extends Exception
{
	//无参数构造器
	public AuctionException(){}
	//带一个参数的构造器
	public AuctionException(String msg)
	{
		super(msg);
	}
}
class AuctionTest
{
	private double initPrice=30.0;
	//因为该方法中显式抛出了AuctionException异常
	//所以此处需要声明抛出了AuctionException异常
	public void bid(String bidprice) throws AuctionException
	{
		double d=0.0;
		try
		{
			d=Double.parseDouble(bidprice);
			
		}
		catch(Exception e)
		{
			//此处完成本方法中可以对异常执行的修复处理
			//此处仅仅是在控制台打印异常的跟踪栈信息
			e.printStackTrace();
			//在此抛出自定义异常
			throw new AuctionException("竞拍价必须是数值,"+"不能包含其它字符");
		}
		if(initPrice>0)
		{
			throw new AuctionException("竞拍价比起价低"+"不允许竞拍!");
		}
		initPrice=d;
	}
}
class SelfException extends RuntimeException
{
	SelfException(){}
	SelfException(String msg){
		super(msg);
	}
}
public class ExceptionTest {

	public static void main(String[] args) throws Exception{
		try{
			int a=Integer.parseInt(args[0]);
			int b=Integer.parseInt(args[1]);
			int c=a/b;
			System.out.println("您输入的两个数相除的结果为:"+c);
		}
		//如果运行程序时输入的第二个参数是0,将发生除0异常
		catch(ArithmeticException ae){
			System.out.println("算术异常!");
		}
		//如果运行程序时输入的参数不够,将会发生数组越界异常
		catch(IndexOutOfBoundsException ie){
			System.out.println("数组越界:运行程序时输入的参数个数不够!");
		}
		//如果运行程序时输入的参数不是数字,而是字母,将会发生数组越界异常
		catch(NumberFormatException ne){
			System.out.println("数字格式异常:程序只能接收整数参数!");
		}
		//如果程序运行时发生其他异常,该异常对象总是Exception类或其子类的实例,Java
		//运行时将调用Exception对应的catch块处理该异常
		catch(Exception e)
		{
			System.out.println("未知异常!");
		}
		Date d=null;
		try{
			System.out.println(d.after(new Date()));
		}
		//当试图调用一个null对象的实例方法或者实例变量时,就会引发NullPointerException异常
		catch(NullPointerException nne){
			System.out.println("空指针异常!");
		}
		catch(Exception e)
		{
			System.out.println("未知异常!");
		}
		
/*
 * 使用一个catch块捕获多种类型的异常时应该注意如下两个地方。
 * 1.多种异常类型之间用竖线(|)隔开
 * 2.异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值
 */
		System.out.println("\n----Java7提供的多异常捕获----");
		try{
			int x=Integer.parseInt(args[0]);
			int y=Integer.parseInt(args[1]);
			int z=x/y;
			System.out.println("x除以y的结果是:"+z);
		}
		catch(IndexOutOfBoundsException|NumberFormatException|ArithmeticException me)
		{
			System.out.println("程序发生了数组越界,数字格式异常,算术异常之一");
			//捕获多异常时,异常变量默认有final修饰,因此下面对异常变量重新赋值会出错
			//me=new ArithmeticException("test");
		}
		catch(Exception e)
		{
			System.out.println("未知异常!");
			//捕获一种类型的异常时,异常变量没有final修饰,可以对其重新赋值
			e=new RuntimeException("test");
		}
		
		System.out.println("\n----访问异常信息----");
		try{
			FileInputStream fis=new FileInputStream("a.txt");
		}
		catch(IOException ioe)
		{
			System.out.println(ioe.getMessage());
			ioe.printStackTrace();
		}
		
		
		
		System.out.println("\n----使用finally回收资源----");
		FileInputStream fis=null;
		try
		{
			fis=new FileInputStream("a.txt");
		}
		catch(IOException ioe)
		{
			System.out.println(ioe.getMessage());
			//return语句强制方法返回
			//return;
			//使用exit退出虚拟机
			//退出虚拟机,不会执行后面的finally语句块
			//System.exit(1);
		}
		finally
		{
			//关闭磁盘,回收资源
			if(fis!=null)
			{
				try{
					fis.close();
				}
				catch(IOException ioe)
				{
					ioe.printStackTrace();
				}
			}
			System.out.println("执行finally块的资源回收!");
		}
		
		boolean a=test();
		System.out.println(a);
		
		System.out.println("\n----Java7的自动关闭资源的try语句 ----");
		try
		(
			//声明、初始化两个可关闭的资源
			//try语句会自动关闭这两个资源
			//BufferedReader br=new BufferedReader(new FileReader("ExceptionTest.java"));
			PrintStream ps=new PrintStream(new PrintStream(new FileOutputStream("sss.txt")))
		)
			{
				//使用这两个资源
				//System.out.println(br.readLine());
				ps.println("直挂云帆济沧海!");
				System.out.println("****");
			}
		
	
		System.out.println("\n----Checked 异常和Runtime异常体系 ----");
/*
 * 所有的RuntimeException类及其子类的实例被称为Runtime异常;
 * 不是RuntimeException类及其子类的异常实例则被称为Checked异常
 * 对于checked异常,Java要求显示捕获并处理该异常,或者显式抛出该异常
 * 如果在方法中显式声明并抛出Checked异常,将会导致方法签名与异常耦合,如果该方法重写父类的方法
 * 则该方法抛出的异常还会受到被重写方法所抛出异常的限制
 * 因此大部分时候推荐使用Runtime异常
 */
		try{
			testone();
		}
		catch(IOException ioee)
		{
			ioee.getMessage();
		}
		
		System.out.println("\n----使用throw抛出异常----");
		try
		{
			//调用声明抛出Checked异常的方法,要么显式捕获该异常
			//要么在main方法中再次声明抛出
			throwChecked(3);
			
			
		}
		catch(Exception e)
		{
			System.out.println(e.getMessage());
		}
		//调用声明抛出Runtime异常的方法既可以显式捕获该异常,也可不理会该异常
		//throwRuntime(3);
		
		System.out.println("\n----自定义异常类----");
		AuctionException ae=new AuctionException();
		System.out.println(ae);
		
		System.out.println("\n----catch和throw同时使用---");
		AuctionTest at=new AuctionTest();
		try{
			at.bid("df");
		}
		catch(AuctionException ae1)
		{
			System.err.println(ae1.getMessage());
		}
		
		System.out.println("\n----Java7增强的throw语句---");
		try{
			new FileOutputStream("q.txt");
			
		}
		catch(Exception ex)
		{
			System.out.println(ex.getMessage());
			throw ex;
		}
		
		System.out.println("\n----Java的异常跟踪栈---");
		firstMethod();
		
}
	public static boolean  test()
	{
		try{
			//因为finally块中执行了return语句
			//下面的return语句失去作用
			return true;
		}
		finally
		{
			//return false;
		}
		
	}
	public static void testone() throws IOException
	{
		//因为FIleInputStream的构造器声明跑出了IOException异常
		//所以调用FileInputStream的代码要么处于Try...catch块中
		//要么处于另一个带throws声明抛出的方法中
		FileInputStream fis=new FileInputStream("aa.txt");
	}
	public static void throwChecked(int a ) throws Exception
	{
		if(a>0)
		{
			//自行抛出异常
			//改代码必须处于try块里,或处于带throws声明的方法中
			throw new Exception("a的值大于0,不符合要求!");
		}
	}
	public static void throwRuntime(int a)
	{
		if(a>0)
		{
			//自行抛出RuntimeException异常,既可以显式捕获该异常
			//也可不理会该异常,把该异常交给该方法调用者处理
			throw new RuntimeException("a的值大于0,不符合要求!");
		}
	}
	public static void firstMethod()
	{
		secondMethod();
	}
	public static void secondMethod()
	{
		thirdMethod();
	}
	public static void thirdMethod()
	{
		throw new SelfException("自定义异常信息!");
	}
}
</span>















©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页