java——异常总结

异常的分类

异常分为检查性异常、运行时异常、Error
1、检查性异常,又叫编译时异常,发生在代码编译过程中,编译器会报错,检查性异常出现时,代码编译无法通过
2、运行时异常是在出现运行过程中出现的,对于运行时异常,可以由程序进行处理,并继续运行程序。
3、Error是致命性的错误,Error类对象由java虚拟机生产并抛出,发生error时,JVM一般会选择线程终止。
注意:所有异常都是发生在程序运行阶段,因为异常的产生是异常类创建了对象,由于编译时异常是发生在编译阶段,编译器可提前预知,并报错,故叫编译时异常。

异常的继承结构

在这里插入图片描述

异常处理的两种方式

1、抛出异常。(throw与throws关键字)
首先在方法声明处使用throws关键字。出现异常时抛给上一级,也可以方法代码块中使用throw关键字,手动抛出异常。(如果是运行时异常抛给了main方法,且main方法没有进行捕捉处理,程序运行并出现错误后JVM会终止程序运行;如果是编译时异常,main方法不进行处理,编译器会无法通过编译。)

代码实例:

public class dome {
	public static void main(String[] args) throws ClassNotFoundException{
		/*
		 * 在main方法中调用dosome方法,dosome方法声明了执行过
		 * 程中会抛出 ClassNotFoundException,而 ClassNotFoundException
		 * 是编译时异常,main方法要进行处理,否则会报错。
		 */
		//
		dosome();//如果main方法不加throws ClassNotFoundException,此处报错
		if(true){
			throw new ClassNotFoundException();//运行到这,main方法手动向JVM抛出异常,JVM结束程序运行。
		}
	}
	
	public static void dosome() throws ClassNotFoundException{
		System.out.println("dosome");
	}
}

2、使用try…catch进行异常捕捉。
上述代码,也可以不在main方法出加 throws ClassNotFoundException,而是把dosome();改为如下代码

try {
		dosome();
	} catch (ClassNotFoundException e) {
		//此处是对发生异常后的处理过程
		e.printStackTrace();
}

异常处理的具体过程(try…catch)

try{}中的代码执行到出异常的语句后,该代码块中后面的代码不执行,进入catch代码块,执行完catch{}代码块后,再执行finally代码块。

try{
	dosome();
	dosome1();//假设这里出了异常,将进入catch代码块,dosome2()不执行
	dosome2();
}catch(exception e){//假设dosome1()会出现ClassNotFoundException,此处可以写该异常的父类,因为
					//有向上转型,Exception e=new ClassNotFoundException.
}catch(){

finally{

}

注意:
(1)、catch()中的括号可以写具体异常类,也可以写该异常类的父类。
(2)、无论try语句块中的代码是否出现异常,finally语句块中的代码一定会最后执行,即使是try语句块和catch语句块中有return;。但是要注意,如果return了一个值,如return a;(a=5),然后在finally语句中对a进行了修改,返回的结果依然是5。即返回的值无法在finally中改变。(但如果在执行到finally子句之前退出了JVM,则该语句块中的代码无法执行。)
(3)、catch语句块可以写多个,但要注意第一个catch的异常类必须是第二个catch异常类的子类,即从上往下是子类到父类的顺序,否则会报错,多个catch也一样。如下列代码:

try {
	FileInputStream fis=new FileInputStream("C:\\Users\\STU\\Desktop");
	fis.read();
} catch (IOException e) {

}catch(Exception e1) {
			
	}

IOException是Exception的子类,这样才能编译通过。(出现异常时,JVM会从第一个catch开始寻找,如果第一个catch是异常父类,则第二个catch永远不会被执行到,故报错。)

自定义异常

自定义异常分为两个步骤:
1、编写一个类继承Exception或者RuntimeException。
2、提供两个构造方法,一个无参构造,一个带有String的构造方法。
(其中传入的String参数是e.getMessage()方法获得的信息。)

public class MyException extends Exception{
	public MyException(){
	}
	public MyException(String s){
		super(s);//调用父类Exception的构造方法。
	}
}

对自定义异常的使用

public class demo {
	public static void main(String[] args) {
		Test t=new Test();
		try {
			t.func();
		} catch (MyException e) {
			// TODO Auto-generated catch block
			System.out.println(e.getMessage());//输出结果为:自定义异常
		}
	}
}
class Test{
	public void func() throws MyException {
		throw new MyException("自定义异常");
	}
}

class MyException extends Exception{
	public MyException() {
	

自定义异常一定要手动创建并手动抛出,不能进行捕捉。因为自己创建的异常对象自己处理没有意义。(JDK源码中的异常类也是这样的形式。)

方法重写中抛出异常的问题

1、父亲犯了错,儿子犯的错误比父亲少。
若一个父类中的一个方法抛出了Exception,则子类在重写该方法时,只能抛出Exception或Exception的子类,也可以不抛出异常。(可以理解为父亲犯了错,儿子犯的错误比父亲少),如下列代码

class Son extends Dad{
	public void DadMeth() throws NullPointerException {
		throw new NullPointerException();
	}
}

class Dad{
	public void DadMeth() throws RuntimeException  {
		throw new RuntimeException();
	}
}

NullPointerException是RuntimeException的子类。

2、父亲不犯错,儿子可以犯运行时错误。
如果父类方法没有抛出异常,则子类重写该方法时,可以抛出RuntimeException或其子类异常。
(可以理解为父亲不犯错,儿子可以犯错),如下列代码:

class Son extends Dad{
	public void Dad() throws NullPointerException{
		throw new NullPointerException();
	}
}

class Dad{
	public void Dad() {
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值