Java学习笔记(36)-异常处理机制

java异常捕获机制

try块:包含着可能出现错误的代码片段

catch块:列举try中出现的错误种类,并有针对性的处理。catch块可以出现1-n次。好的编程习惯,在最后一个catch捕获Exception异常。

注意:

catch的捕获是由上至下的,所以不要把父类异常写在子类异常的上面,否则子类异常永远没有机会处理!

java中抛出异常:

java虚拟机(jvm)在运行程序时,一旦在某行代码运行时出现了错误,jvm会创建这个错误的实例,并抛出。这时jvm会检查出错代码所在的方法是否有try捕获,若有,则检查catch块是否有可以处理该异常的能力。若没有,则将该异常抛给该方法的调用者。以此类推,直到抛至main方法外仍没有解决。那么jvm会终止该程序。





package day01;
/**
 * java异常处理机制
 * 我们在程序中可以捕获的是Exception的子类异常
 * 而java中的异常有两大类。
 * Exception:程序级别的异常,我们可控
 * Error:系统级别的异常,我们不可控。
 * 所以我们关心的是Exception的相关子类!
 * 
 * 异常处理语句
 * try{
 * 	可能发生异常的代码片段
 * }catch(Exception e){
 * 	//列举代码中可能出现的异常类型,当出现了列举的异常类型后,在这里处理
 * }
 * try{
 * }catch(Exception e){
 * }
 * @author Administrator
 *
 */
public class DemoException {
	public static void main(String[] args) {
		try{
//			String info = null;
			String info1 = "hello";
			//这里会引发空指针异常!
//			System.out.println("这个字符串长度:"+info.length());
			System.out.println("第10个字符是:"+info1.charAt(9));
		}catch(NullPointerException e){
			System.out.println("这里的字符串是空的!");
		}catch(StringIndexOutOfBoundsException e){
			System.out.println("字符串没有那么长!");
		}catch(Exception e){
			/**
			 * 良好的习惯,在异常捕获机制的最后书写catch(Exception e)
			 * 捕获未知的错误(或不需要针对处理的错误)。
			 */
		}
		
		System.out.println("程序结束了!");
	}
}

throw关键字:用于主动抛出异常

使用环境:

我们常在方法中主动抛出异常。但不是什么情况下我们都应该抛出异常。原则上,自身决定不了的应该抛出。

方法中什么时候该自己处理异常什么时候该抛出?

方法通常有参数,调用者在调用我们的方法帮助解决问题时通常会传入参数,若我们方法的逻辑是因为参数的错误而引发的异常应该抛出,若是我们自身的原因应该自己处理。

package day01;

/**
 * throw关键字,可以主动抛出一个异常
 * 
 * 应用环境: 当我们的方法出现错误时,这个错误我们不应该去解决,而是
 * 通知调用方法方去解决时,会将这个错误告知外界,而告知外界的方式就是throw异常(抛出异常)
 * 
 * @author Administrator
 *
 */
public class DemoThrow {
	public static void main(String[] args) {
		try{
			/**
			 * 通常我们调用方法时需要传入参数的话,那么这些方法都不会自动处理异常
			 * 而是将错误抛给我们解决。
			 */
		String result = getGirlFirend("女神");
		System.out.println("我追到了女神吗?"+result);
		}catch(Exception e){
			//我们应该在这里捕获异常并处理。
			System.out.println("没追到。。。");
		}
	}

	/**
	 * 介绍女朋友 name 女朋友的名字 return 是否同意
	 */
	public static String getGirlFirend(String name) {

		try {
			if ("春哥".equals(name)) {
				return "行";
			} else if ("曾哥".equals(name)) {
				return "行";
			} else if ("我女朋友".equals(name)) {
				return "不行";
			} else {
				/**
				 * 当出现了错误(可能是业务逻辑上的,不一定是真实异常) 我们可以主动向外界抛出一个异常!
				 */
				throw new RuntimeException("人家不干");
			}
		} catch (NullPointerException e) {
			throw e;// 错误了不解决,抛给调用者解决。
		}
	}
}

throws关键字:

声明方法的时候,我们可以同时声明可能抛出的异常种类,通知调用者强制捕获。

就是所谓的丑话说前面。

注意区分throw和throws关键字。笔试常问。

throws可以在方法声明时声明抛出的异常。原则上throws声明的异常,一定要在该方法中抛出。否则没有意义。相反的。

若方法中我们主动通过throw抛出一个异常,应该在throws中声明该种类异常,通知外界捕获。

package day01;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * throws关键字
 * 声明抛出异常的种类
 * 
 * 作用是通知调用者必须捕获的异常
 * @author Administrator
 *
 */
public class DemoThrows {
	public static void main(String[] args) {
		try{
			Date today = stringToDate("2013-05-20");
			//catch中必须含有有效的捕获stringToDate方法throws的异常
		}catch(ParseException e){
			/**
			 * 输出这次错误的栈信息
			 * 可以直观的查看方法调用过程和出错的根源。
			 */
			e.printStackTrace();
		}
	}
	/**
	 * 将一个字符串转换为一个Date对象 java.util.Date
	 * 抛出的异常是字符串格式错误
	 * @param str
	 * @return
	 */
	public static Date stringToDate(String str)
			throws ParseException{
		SimpleDateFormat format = 
				new SimpleDateFormat("yyyy-MM-dd");
		/**
		 * SimpleDateFormat的parse方法在声明的时候就使用了throws强制我们
		 * 调用parse方法时必须捕获ParseException
		 * 我们的做法是添加try-catch捕获该异常,或者在我们的方法
		 * 声明中也追加这种异常的抛出。
		 */
		Date date = format.parse(str);
		return date;
	}
}

java中的异常Exception分为:

运行时异常:编译时不检查异常

可检查异常:编译时检查

RuntimeException:运行时异常。

若方法中抛出该类异常或其子类,那么声明方法时可以不在throws中列举该类抛出的异常。

package day01;

import java.text.ParseException;
import java.util.Date;

/**
 * 抛出异常的规范
 * @author Administrator
 *
 */
public class DemoCheckException {
	public static void main(String[] args) {
		try{
			Date date = stringToDate("1988-02-25");
		}catch(ParseException e){
			e.printStackTrace();
		}
	}
	/**
	 * throws的位置:
	 * 方法声明时参数列表的后面,方法体前半个大括号前面
	 * @param str
	 * @return
	 * @throws ParseException
	 */
	public static Date stringToDate(String str) throws ParseException{
		if(str == null){
			/**
			 * 我们在方法中主动抛出异常,应该在方法声明时声明该异常的抛出
			 * 
			 * NullPointerException是非检查异常(RuntimeException子类)
			 * 所以我们抛出该类异常实例时,方法声明处无需添加throws来列举该类异常的抛出。
			 * 编译器在编译该类时也忽略对这类异常抛出的检查(编译时不看他是不是在throws中被列举)。
			 */
//			throw new NullPointerException("有错误");
			/**
			 * 抛出非RuntimeException异常,这类异常称为检查异常
			 * 编译器在编译该类时若发现方法中抛出了此类异常。那么一定会检查方法声明
			 * 处是否含有throws这类异常的声明,若没有就判定为语法错误。编译不通过!
			 */
			throw new ParseException("有错误",0);
		}
		return null;
	}
}
package day01;
/**
 * try-catch中的finally块
 * 
 * finally块定义在catch块的最后。只能出现一次。(0-1次)
 * 
 * 无论程序是否出错都会执行的块!
 * 无条件执行!
 * 注意final和finally的区别。
 * @author Administrator
 *
 */
public class DemoFinally {
	public static void main(String[] args) {
		try{
			String info = "23223232332";//null
			System.out.println("字符串第10个字符"+info.charAt(9));
		}catch(NullPointerException e){
			e.printStackTrace();
		}catch(StringIndexOutOfBoundsException e){
			e.printStackTrace();
		}finally{
			//里面的语句无条件执行!
			System.out.println("finally!!!");
		}
		System.out.println("程序结束了");
	}
}
package day01;
/**
 * finally面试题
 * @author Administrator
 *
 */
public class FinallyDemo {
	public static void main(String[] args) {
		System.out.println(test(null)+","+test("0")+","+test(""));
		/*
		 * 输出结果?
		 * 4,4,4
		 * finally无条件执行
		 */
	}
	public static int test(String str){
		try{
			return str.charAt(0)-'0';
		}catch (NullPointerException e){
			return 1;
		}catch (RuntimeException e){
			return 2;
		}catch (Exception e){
			return 3;
		}finally{
			return 4;//它return前面的return都无效了
		}
	}
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值