异常的概念

异常的英文单词是exception,字面翻译就是“意外、例外”的意思,也就是非正常情况。java异常是java提供的用于处理程序中错误的一种机制。所谓错误是指在程序运行的过程中发生的一些异常事件;事实上,异常本质上是程序上的错误。

10.2 异常的分类

异常主要分为运行时异常和非运行时异常:
运行时异常都是Unexceptionably类及其子类异常,如Interception、Unexceptionably等, 这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的, 程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常是Unexceptionably以外的异常。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如Conception、Exceptional等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

10.3 异常体系结构

exceptionless 数据默认存在哪里了_java


1.Error:称为错误,由Java虚拟机生成并抛出,包括动态链接失败,虚拟机错误等,程序对其不做处理。

2.Exception:所有异常类的父类,其子类对应了各种各样的可能出现的异常事件,一般需要用户显示的声明或捕获。

3.0Runtime Exception:一类特殊的异常,如被0除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显示的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。

其实异常部分主要讲的就是五个关键字:try、catch、finally、throw、throws:

1.try语句:
try{……}语句制定了一段代码,这段代码就是一次捕获并处理例外的范围。在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理。如果没有例外发生,所有的catch代码段都被略过不执行。

2.catch语句:
在catch语句块中是对异常进行处理的代码,每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
在catch中声明的异常对象(catch(Exception e))封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息。

3.finally语句:
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前,能够对程序的状态做统一的管理。
无论try所指定的程序块中是否抛出例外,finally所指定的代码都要执行。
通常在finally语句中可以进行资源的清除工作,如:
  1)关闭打开的文件
  2)删除临时文件
  3)……
  
**4.throws语句:
throws关键字的最大好处是:在方法中不处理任何的异常,而交给被调用处处理。

5.throw语句:
在程序中可以使用throw关键字人为的抛出一个异常。在异常处理中,实际上每次产生异常的时候都是产生了一个异常类的实例化对象。那么此时,也可以通过抛出异常对象的方式完成。
**

10.4 常见的异常和解决方式

下面就看一下常见的一些异常和处理:
示例(封装类):

package com.ambow.test;
/**
 * 玩家封装数据
 * 
 * */
public class Player {
	private int id;//表示玩家的编号
	private String loginname;//表示玩家用户名
	private String password;//表示密码
	private String nickname;//表示玩家昵称
	private String sex;//表示玩家性别
	private int age;//表示玩家年龄
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getLoginname() {
		return loginname;
	}
	public void setLoginname(String loginname) {
		this.loginname = loginname;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getNickname() {
		return nickname;
	}
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

示例:

package com.ambow.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class ExceptionDemo {
	public void say(Player pla){
		
	}
	/*
	 *异常的概念:本质上就是程序的错误
	 *异常的分类:1.运行时异常 exception:程序运行时发生的异常,可以不处理,要尽量避免
	 *		  2.非运行时异常error:可以在编译期被检测到,必须要处理
	 * 常见的异常:
	 * 		1.数组下标越界异常
	 * 		2.空指针异常
	 * 		3.算术异常
	 * 		4.输入不匹配异常
	 * 		5.类型转换异常
	 * 		6.解析异常
	 * 		7.类路径丢失异常
	 * 		8.参数类型不匹配异常
	 * */
	public static void main(String[] args) throws ParseException, ClassNotFoundException {
		//java.lang.ArrayIndexOutOfBoundsException:数组下标越界异常
		//解决方案:查看数组的下标是否有异常
		/*int[] ints=new int[10];
		ints[10]=5;*/
		
		//java.lang.NullPointerException:空指针异常
		//解决方案:查看你的赋值(引用,对象)或者传值(引用,对象)是否丢失
		/*Player pla=null;
		System.out.println(pla.getLoginname());*/
		
		//java.lang.ArithmeticException:算术异常
		//解决方案:说明的你的数学逻辑出问题,将其修改就可以
		//System.out.println(100/0);
		
		//java.util.InputMismatchException:输入不匹配异常
		//解决方案:使用异常的处理
		/*Scanner sc=new   Scanner(System.in);
		System.out.println("请输入一个数字:");
		sc.nextInt();*/
		
		//多态
		/*Object o=new Integer(5);
		System.out.println(o);
		//java.lang.ClassCastException:类型转换异常
		//解决方案:后面说。。。。
		String s=(String)o;
		System.out.println(s);*/
		
		/*SimpleDateFormat sf=new SimpleDateFormat("yyyy/MM/dd");
		//java.text.ParseException:解析异常
		//解决方案:查看解析的格式是否一致
		Date date=sf.parse("2018-07-16");
		System.out.println(date);*/
		
		//java.lang.ClassNotFoundException:类路径丢失异常
		//Class.forName("com/tjzs/a/ExceptionDemo.java");
		
		//java.lang.lllegalArgumentException:参数类型不匹配异常
		//解决方案:参看传递的参数是否与定义的参数一致
	}
}

10.5 异常的执行原理

执行try时,如果发生异常。JVM会自动创建一个相应类型的异常对象。然后catch块会检查异常的类型,如果发生的异常恰恰和catch观察的类型一样,则由相应的catch处理该异常。所以,catch块可以有多个,并且按照从前往后的顺序检查。一般把小的异常类型放在前面,大的类型(Exception)放到后面

10.6 异常的处理

异常的处理主要包括捕捉异常、程序流程的跳转和异常处理语句块的定义等。
在Java程序里,异常对象是依靠try/catch语句来捕捉和处理的。

try{
 …… //try语句块,可能产生异常情况
 }catch(异常类型 异常对象){
 …… //catch语句块,对异常进行处理
 }finally{
 … //无论是否有异常出现,都必须执行
 }

在try块之后,可能有许多catch块,每一个都处理不同的异常.finally语句只用来控制从try—catch语句转移到另一部分前的一些必要的善后工作,这些工作包含了关闭文件或释放其他有关系统资源。finally语句执行的是一种强制的无条件执行,即无论在程序中是否出现异常,也不管出现的是哪一种异常,即使try代码块中包含有break、continue、return或者throw语句,都必须执行finally块中所包含的语句。

10.5.1 异常的捕获

异常捕获的基本思想:
当一个异常被抛出时,应该有专门的语句来捕获这个被抛出的异常对象,这个过程被称为捕捉异常。
Java的异常处理是通过3个关键词来实现的:try-catch-finally。用try来执行一段程序,如果出现异常,系统抛出(throws)一个异常,可以通过它的类型来捕捉(catch)并处理它,最后一步是通过finally语句为异常处理提供一个统一的出口,finally所指定的代码都要被执行(catch语句可有多条;finally语句最多只能有一条,根据自己的需要可要可不要)。
异常捕获的语法:

try{
 可能出现异常的语句
 }catch(异常类 异常对象){
 异常处理
 }catch(异常类 异常对象){
 异常处理
 }
 …
 finally{
 异常的出口;
 }

示例:

package com.ambow.test;
/**
 * 处理异常的方式:
 * 		1.try-catch模块(异常的处理)
 * 		2.通过throws关键字来抛出异常(异常的抛出)
 * */
public class ExcptionDemo2 {
	/*try-catch的语法格式:
	 * 一个try后面可以跟多个catch语句,也就是说一个try语句中可以捕获多个异常,
	 * 但是在具体执行时只会捕获出现的第一个异常
	 * try{
	 * 		//可能出现异常的语句
	 * 		retrun;
	 * 		}catch(Excption e1){
	 * 		//异常的信息    e.。。。。。
	 * 		//处理异常的代码
	 * 		}catch(Excption e2){
	 * 		//异常的信息    e.。。。。。
	 * 		//处理异常的代码
	 * 		}.....
	 * 		finally{
	 * 		//不管你有没有异常都会执行finally中的语句块,但是finally语句块不是必须的,可以不写
	 * 		**加了finally语句块,只要try开始执行,即使遇到retrun,finally仍然执行**
	 * 		}
	 * */
	public static void main(String[] args) {
		try{
			Player pla=null;
			System.out.println(pla.getLoginname());
			System.out.println(100/0);
			System.out.println("123");
			return;
		}catch(NullPointerException e){
			//用来告诉我们出现了什么异常,它是爆红的
			//e.printStackTrace();
			System.out.println("出现了空指针异常");
		}catch(ArithmeticException e){
			//用来告诉我们出现了什么异常,它是爆红的
			//e.printStackTrace();
			System.out.println("出现了算术异常");
		}finally{
			System.out.println("不管有没有异常我都会执行");
		}
}

10.5.2 异常的抛出

异常抛出的基本思想:
Java应用程序在运行时如果出现了一个可识别的错误,就会产生一个与该错误相对应的异常类的对象,这个对象包含了异常的类型和错误出现时程序所处的状态信息,这个异常对象首先被交给Java虚拟机,由虚拟机来寻找具体的异常处理者。在Java中把产生异常对象并将其交给Java虚机的过程称为称为异常的抛出。
异常抛出的方式:
1.throws:throws一般出现在方法声明上,代表方法可能出现的异常。throws只是一个声明,告诉方法的调用者,调用该方法时需要处理某种或某几种异常 。真的发生异常时,方法本身可以不处理,而是由方法的调用者处理。throws可以声明多种类型异常。

2.throw:我们只需要创建相应类型的异常对象,然后通过throw(抛出)异常,就能触发一个异常,该种抛出异常的方式比较直接。

示例(throws):

package com.ambow.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
 * 处理异常的方式:
 * 		1.try-catch模块(异常的处理)
 * 		2.通过throws关键字来抛出异常(异常的抛出)
 * 
 * */
public class ExcptionDemo2 {
	public static void main(String[] args) {
		SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
		try {
			sf.parse("2018/07/16");
		} catch (ParseException e) {
			// 提示我们异常出现在哪一行
			e.printStackTrace();
			System.out.println("出现了解析异常");
		}
		ExcptionDemo2 ee=new ExcptionDemo2();
		try {
			//调用将异常抛在方法上的方法时,需要抛异常,因为throws只是一个声明
			//throws声明告诉方法调用者,调用该方法是需要处理某种或者多种异常
			ee.method();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	public void method() throws ParseException{
		SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
		sf.parse("2018/07/16");
	}
}

示例(throw)

if(age < 0){
throw new Exceptional("年龄不能为负数!");
}

10.5.3 throw和throws的区别

1.throws关键字通常被应用在声明方法时,用来指定可能抛出的异常。多个异常可以使用逗号隔开。当在住函数中调用该方法时,如果发生异常,就会将异常抛给指定异常对象。
2.throw关键字通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行。通常throw抛出异常后,如果想在上一级代码中来捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法声明中指明要抛出的异常;如果要捕获throw抛出的异常,则必须使用try{}catch{}语句。

10.5.4 自定义异常

可以通过继承Exception类,创建自定义的异常类型。自定义异常,可以用来处理业务逻辑上的错误,重写getMessage或者其它方法,来设置message属性值,从而设置自定义异常的输出信息。
示例(自定义异常类):

package com.ambow.test;
/**
 * 1.自定义异常类
 * 2.继承Exception类
 * 3.创建有参构造函数并且调用父类中的有参构造函数
 * */
public class BankException extends Exception {
	public BankException(String message){
		super(message);
	}
}

示例(使用):

package com.ambow.test;
public class Bank {
	//定义银行卡的余额
	private double blance;
	public double getBlance() {
		return blance;
	}
	public void setBlance(double blance) {
		this.blance = blance;
	}
	//存款方法
	public double add(double money){	
		return this.blance+=money;
	}
	//取款方法
	public double sub(double money) throws BankException{
		if(this.blance-money>=0){
			this.blance-=money;
		}else{
			throw new BankException("余额不足");
		}
		return this.blance;
		
	}
}

示例(测试):

package com.ambow.test;
public class Test {
	public static void main(String[] args) throws BankException {
		Bank b=new Bank();
		b.setBlance(5000);
		double d=b.add(3000);
		System.out.println("存入3000元以后的余额为:"+d);
		d=b.sub(9000);
		System.out.println("取入9000元以后的余额为:"+d);
	}
}

示例结果:

说明:通过throw在方法内部抛出一个自定义异常。显示信息,就是Message的内容;方法内部抛出异常后,本身不处理,通过throws声明。方法调用者,同时处理方法的异常

异常
 异常的分类
 常见异常
 异常的处理方式:
 捕获 try-catch-finally
 抛出 throws
 自定义异常 throw