java基础知识--异常

9.01 异常的由来

代码在运行时期发生的问题就是异常。在java中使用Exception来描述异常,throwable是Java 语言中所有错误或异常的超类,可以通过查看API。

异常内容:

异常名称,异常产生原因,异常发生的位置,异常再生的线程。
(名称和原因我们可以自定义,位置和线程由JVM决定)

9.02 常见异常

ArrayIndexOutOfBoundsException: 数组下标越界异常,当出现超过数组下标范围0-array.length-1范围外的下标时,出现这个异常

ArithmeticException:算数异常,在除数为0时报出异常

ClassCastException:类型转换异常,当父类引用指向子类对象的多态时,如果调用的引用不是父类的话,无法转换,报出异常

NullPointerException:空指针异常,当创建对象后,其中的String类型数据指向空,此时去使用这些数据会报异常

FileNotFoundException:找不到文件异常,在I/O流里因为想要使用文件,但是文件不存在所产生的异常。

NoSuchMethodException:没有这个方法异常,当调用(静态或者实例)类的方法,而类已经不再具有时,抛出这个异常。

SecurityException:安全检测异常,由安全管理器抛出,表示存在安全侵犯UnknownHostException: 找不到主机异常,使用socket关键字访问时,找不到主机

IllegalArgumentException: 非法参数异常,如有些方法的参数需要int,你传入String引用数据类型

MalformedURLException:URL解析格式异常,当使用为URL格式的网址时,找不到协议,或者URL格式非法。

InputMismacthException:输入不匹配异常。输入要获取int类型,结果你给出的时float。

NumberFormatException:转换字符串格式异常,当打算把字符串的数据转换为int型时不匹配发出的异常,如"abc"转为int失败。

9.03 异常的产生及模拟处理

异常的产生

基本是由JVM自动检测的,也可以人为的手动抛出异常。throw 异常对象;(throw只能在函数内部,属于执行语句)

模拟处理:

package part1.异常;
public class ExceptionDemo {
	public static void main(String[] args) {
		int[] a=new int[4];
		int[] b=new int[1024*1024*1024];  //异常 堆溢出
		show(a,5); //角标越界
		show(null,2);	//异常 数组为空
		System.out.println("嘿嘿");
	}

	private static void show(int[] a, int index) {
      //JVM模拟:
		/*
		if(a==null){
			throw new NullPointerException("数组为空!");
		}
		if(index<0||index>=a.length){
			throw new ArrayIndexOutOfBoundsException("数据角标越界:"+index);
		}
		*/
		System.out.println(10/0);
		System.out.println(a[index]);
	}
}

9.04 异常体系

问题很多,意味着描述的类也很多 将其共性进行向上抽取,就形成了异常体系。
Throwable是异常的的最终父类。(除object类外–object是任何类的父类。)

最终问题分成两大类:

1.一般不可处理 Error
2.可处理 Exception

在这里插入图片描述
Error,Exception:无论是哪个,都是问题,问题发生就应该抛出,让调用者知道,并可以处理。所以,该体系的特点就在于Throwable及其所有的子类都具有可抛性。

Error特点:

是由JVM抛出的严重性的问题,这种问题发生一般不针对性处理,直接修改程序,比如类找不到,数据内存过大。

Exception特点:

是由虚拟机或Java throw抛出的一般性错误(能够有解决方案——程序不一定终止!)

该体系的特点:

子类的后缀名都是用其父类名后缀

9.05 自定义异常

就是按照项目实际需求 定义出所需的异常类

自定义类继承Exception或其子类 通过构造函数定义异常信息,都是找父类。 通过throw将自定义异常抛出。

电脑有时会出现蓝屏的问题,将蓝屏问题定义 一个异常类。
class BlueScreenOfDeath extends Exception{
	BlueScreenOfDeath(String message){
		super(message);
	}
}

定义完成后,throw,throws,try-catch-finally,和Java自带的异常用法相同。

9.06 异常的分类

主要分为两大类:

1.编译时被检测异常(编译时异常):

编译时异常,这种问题一旦出现,希望在编译时就进行检测,让这种问题有相对应的处理方式。这种问题都可以针对性处理。

只要是Exception和其子类,除了RuntimeException体系。

2.编译时不检测异常(运行时异常):

运行时异常,这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致,也有内部原因。这种问题一般不处理,直接编译通过,在运行时,让调用者调用时程序强制停止,让调用者对代码进行修正。

就是Exception中的RuntimeException和其子类。

9.07 throw与throws的区别

1.throws使用在函数上;throw使用在函数内。
2.throws抛出的是异常类,可以抛出多个,用逗号隔开;throw抛出的是异常对象。

9.08 异常的处理

对于Exception而言 解决方案一般有两种形式
声明 throws

通过声明提前告诉调用者该函数可能会存在问题
如果问题发生 首先会反馈给函数自身 函数自身再将该问题反馈给调用者 由调用者自行解决
对于该函数而言 确实是一种解决方案 但是并没有在函数内部实质解决 甩锅~	
throws 只能在函数定义之后 函数体之前
throws 后面只能跟异常类 可以多个类名 类名之间,分隔

捕获 try-catch-finally

先尝试运行某段代码try
如果该段代码出现问题 则立马解决 catch
无论代码是否出错 将都会执行的代码放入finally

具体格式:

try{
	//需要被检测异常的代码
}catch(异常类 变量){	//该变量用于接收发生的异常对象
	//处理异常的代码
}finally{
	//一定会被执行的代码
}

异常处理的原则

1.函数内容如果抛出需要检测的异常,那么函数上必须声明。否则必须在函数内用trycatch捕捉,否则编译失败。
2.如果调用到了声明异常的函数,要么trycatch要么throws,否则编译失败。
3.什么时候catch,功能内部可以解决用,解决不了用throws,由调用者解决。
4.一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理。内部有几个需要检测的异常,就抛几个异常,抛几个,就catch几个。

注意:

异常在子父类中的特点(编译时异常)
1.父类函数如果没有声明异常 子类就不能声明 只能捕获
2.父类如果声明异常 子类只能声明父类异常的子类或子集
(运行时异常)解决与否都可以

9.09 异常中有return的情况

没有异常的情况下 try里有return   try->finally
没有异常的情况下 catch里有return   try->finally->之后
没有异常的情况下 finally里有return   try->finally 一旦有 之后则不执行

有异常的情况下 try里有return  try-catch-finally->之后
有异常的情况下 catch里有return   try->catch->finally
有异常的情况下 finally里有return   try-catch-finally 一旦有 之后则不执行

没异常的情况下
 try catch里有return  try->finally之后不执行
有异常的情况下
 try catch里有return  try->catch->finally

综上而言  不推荐try-catch-finally里写return  但是理论可写

9.10 本章小结

1.异常处理使一个方法能够抛出一个异常给它的调用者。

2.Java异常是扩展自java.lang.Throwable 的类的实例。Java 提供大量预定义的异常类,例如, Error、Exception、RuntimeException、ClassNotFoundException、Nul1PointerException 和 ArithmericException。也可以通过扩展 Exception 类来定义自己的异常类。

3.异常发生在一个方法的执行过程中。RuntimeException 和 Error 都是免检异常、所有其他的异常 都是必检的。异常处理和文本 I/O 

4.当声明一个方法时,如果这个方法可能抛出一个必检异常,则必须进行声明,从而告诉编译器可能会出现什么错误。 

5.声明异常的关键字是 throws, 而抛出异常的关键字是 throw。 

6.如果调用声明了必检异常的方法,必须将该方法调用放在 try 语句中。在方法执行过程中出现异常时,catch块会捕获并处理异常。 

7.如果一个异常没有被当前方法捕获,则该异常被传给调用者。这个过程不断重复直到异常被捕获或 者传递给main 方法。 

8.可以从一个共同的父类派生出各种不同的异常类。如果一个 catch块捕获到父类的异常对象,它也 能捕捉这个父类的子类的所有异常对象。 

9.在 catch 块中,异常的指定顺序是非常重要的。如果在指定一个类的异常对象之前,指定了这个异 常类的父类的异常对象,就会导致一个编译错误。 

10.当方法中发生异常时,如果异常没有被捕获,方法将会立刻退出。如果想在方法退出前执行一些任务,可以在方法中捕获这个异常,然后再重新抛给它的调用者。 

11.任何情况下都会执行 finally 块中的代码,不管 try 块中是否出现了异常,或者出现异常后是否捕获了该异常。 

12.异常处理将错误处理代码从正常的程序设计任务中分离出来,这样就会使得程序更易于阅读和修改。 

13.不应该使用异常处理代替简单的测试。应该尽可能地使用if 语句来进行简单的测试,将异常处理留作处理那些无法用if 语句处理的场景。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值