异常:
生活中的异常:
比如每天早起去上班,时间大概半小时;
一旦哪天出现意外的情况,那么此时就是异常,就会中断,
此时就需要找其他方法来上班。
程序中的异常:
比如0不能作为除数,不然就会有异常。
如果用寻常的机制去处理,会很浪费时间,代码臃肿,
并且以后也很难堵住所有的“漏洞”。
所以需要异常处理机制。
什么是异常
异常是指在程序的运行过程中所发生的不正常的事件,
它会中断正在运行的程序。
java程序中的不支持现象
(Error:编译出错,运行出错 :不能运行(比如 jdk包错误)
Exception:异常、中断程序运行
warning:警告 可优化的空间 并不是都要优化)
异常体系结构:
常见异常:
SqlException 数据库异常
NullPointerException 空指针异常
ClassCastException 类型转换异常
NumberFormatException 数值转换异常
IndexOutOfBoundsException 下标越界异常
Throwable:Exception和Error类的父类
Exception:由Java应用程序抛出和处理的非严重错误
Error:仅靠程序本身无法恢复的严重错误
RuntimeException: 是Exception的子类
运行时异常,不要求程序必须做出处理 。
运行过程中根据具体值才能决定是否会出异常。
CheckedExceptiond异常:
程序设计时考虑很可能会发生这种情况
程序必须处理该类异常,不处理会编译报错
如SQLException、classNotFoundException.
Checked也叫检查异常,UnChecked非检查异常
什么是异常处理
Java编程语言使用异常处理机制为程序提供了错误处理的能力,
处理完成之后,才能正常运行。
Java异常处理机制
Java的异常处理是通过5个关键字来实现的:
try、catch、 finally、throw、throws
try-catch-finally块:处理异常
try{//可能发生异常的代码,放在try块中
}catch(异常类型 e){//捕获的异常
//e 是作用域里面 出去就没用了 只是个名字
//对异常的处理 , 放在catch块中
}catch(异常类型 e){
}finally{//主要是用于关闭某些必须关闭的东西
//一定会执行的代码
}
注意点:
catch里必须要加 e 对象 来捕获 ,不管有没有用到。
Exception异常要放在最下面。
catch 从上到下 一旦捕捉到异常了,下面的其他catch不会执行。
快捷键:Alt + shift + z
finally和catch 至少有一个
catch里的内容主要有三个:(在catch块中处理异常)
System.err.println("xxxxxxxxxxxxx");
//自定义输出 err输出的语句是红色的 并且只有这句话。
e.printStackTrace();//调用方法输出异常信息
//printStackTrace()的堆栈跟踪功能显示出程序运行到当前类的执行流程
System.out.println(e.getMessage()); //返回异常信息描述字符串
//只适用于特定情况,它是printStackTrace()输出信息的一部分
使用try-catch块捕获异常,分为三种情况:
第一种:正常
public void method(){
try {
// 代码段(此处不会产生异常) 1
} catch (异常类型 ex) {
// 对异常进行处理的代码段 2
}
// 代码段 3
}
当没有异常,那么会先执行1,再执行3。
第二种:出现异常
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段 4
}
// 代码段 5
}
当出现异常,先执行1,再执行2,然后执行4,最后是5。
当发生异常的时候,产生异常对象,然后进行异常类型匹配,
会进入到catch里面,来匹配所造成的异常,然后程序继续执行后面的代码。
注意点:
异常会直接中断,后面的程序就不会执行,直接去匹配异常类型。
异常是一种特殊的对象,
类型为 java.lang.Exception或其子类
第三种:异常类型不匹配
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段 4
}
// 代码段 5
}
先执行1,再执行2。
当发生异常时,产生的异常对象匹配不到,那么程序就会中断运行。
Finally:
**Finally:**是否发生异常都执行,不管有没有return。
不执行的唯一情况:
System.exit(1);
中断程序,退出Java虚拟机
1是退出的状态码 只是个参数 什么都可以 最好有意义 0 1 -1。
存在return的try-catch-finally块
1.虽然return是跳出方法,但是还是会执行finally里面的语句。
2.当返回值为int型时,举例:
public int b() {
int i = 0;
try {
i++;
System.out.println(1/0);
return i;
}catch(ArithmeticException e) {
i++;
return i;
}finally {
i++;
return i;
}
执行方法b,结果为:3,但是return 2,和return3 都执行了,
只是被覆盖了,只能有一个返回值。当去掉finally中的return,那么结果是2。
3.当是对象类型时,返回出来的是地址,地址的属性改变了,那就都变了,
所以finally里面的return不管有没有,结果都是一样。
未捕获的异常被finally中的return覆盖了 (难点)
多重catch块
引发多种类型的异常
- 排列catch 语句的顺序:先子类后父类
(不能把大类型放在前面,不然报错) - 发生异常时按顺序逐个匹配
- 只执行第一个与异常类型匹配的catch语句
异常处理方式-throws
如果在一个方法体中抛出了异常,如何通知调用者?
throws:声明某个方法可能抛出的各种异常,多个异常用逗号隔开。
- 写在出现异常的方法名小括号后面
- 自己不处理可能发生的异常,
由下一个调用者继承这个异常,是否处理交给下一个人。
方式1:调用者处理异常
方式2:调用者继续声明异常
main()方法声明的异常由Java虚拟机处理
抛出异常,产生异常
除了系统自动抛出异常外,有些问题需要程序员自行手动抛出异常
使用throw抛出异常(throw一个异常类的对象。)
public class Demo {
public void add() throws Exception{
System.out.println(1 + 1);
if(true) {
throw new Exception("自己手抛的异常");
//自定义异常
}
}
public static void main(String[] args) {
Demo d = new Demo();
try {
d.add();
}catch(Exception e) {
System.err.println(e.getMessage());
}
}
}
- throw语句下面不能再写语句, 不然报错,因为会立刻中断。
- throw new Exception(“自己手抛的异常”); 当写成这个样子,
那么必须要处理,用throws来抛相对应的异常 - throw new RuntimeException(“自己手抛的异常”);
运行期异常表面不会发生错误,(不用写throws)
但运行时还是会有异常出现,所以还是要用try - catch。 - e.getMessage()得出的结果就是throw里面的写的话。
throw与throws的区别:
自定义异常
当JDK 中的异常类型不能满足程序的需要时,可以自定义异常类
使用自定义异常的步骤:
1.定义异常类,继承一个已知的异常类型
(继承Throwable类、继承Excepion 或者RuntimeException)
如果要定义运行期异常,一般继承RuntimeException
如果要定义Checked异常,一般继承Exception
Excepion是必须被捕获(要处理)的异常,用throws抛出
RuntimeException不需要抛出,但是该出还是出异常的。
2.根据需要编写构造方法,继承父类的实现
3.实例化自定义异常对象
4.使用throw抛出
举例:(定义异常类型)
public class WrongException extends RuntimeException{
public WrongException(String message) {
super(message);
}
}
然后用 throw new WrongAgeException(xxx);(使用异常)
()里面 就是 message输出的话。
try catch 里面也是这个异常。
人为定义的异常也能用。
异常处理原则
- 异常处理与性能
- 异常只能用于非正常情况
- 不要将过于庞大的代码块放在try中
- 在catch中指定具体的异常类型
- 需要对捕获的异常做处理
异常分为Checked异常和运行时异常
Checked异常必须捕获或者声明抛出
运行时异常不要求必须捕获或者声明抛出
异常处理办法:
1、条件结构,尽量避免异常发生(有些情况无法这样处理)
2、try - catch 语句
3、在方法上抛出异常、给下一个访问者来处理
题外话:
return:
int a =1;
int add() {
if(a=0)
return 8;
else
return 6;
}
上面这种情况就需要有第二个return,不然就会报错。
当你执行异常的时候,会更新出(绕路产生)另外一个栈(栈也是对
象),但是这两个栈,谁先谁后,不清楚,并且旧的异常和没执行的程序还
在,如果用垃圾回收gc ,gc也会占内存 。
INFINITY:无穷大
java.lang.Double下的Infinity:
当被除数为浮点数(且不能为0或0.0)或被除数为0.0时,
控制台输出的结果都为Infinity。
double i = 1.0 / 0;
System.out.print(i); //Infinity
Alt + shift + N :
空指针异常:
User user = new User();
user = null;
//null 代表消除空间 但不是消除地址,
地址是计算机里的一个标识,是个硬件。
此时输出就会出现java.lang.NullPointerException
习惯:
记得保存代码,以后工作通常用接口
类名 对象名 = new 类名() 从后往前写(有灵魂)
整理快捷键:Ctrl shift s
导包快捷键 :Ctrl+ shift+ o
撤销反撤销:Ctrl + y
光标移动到最前面:fn + 左键(home键)
----2021.08.12