目录
主题:异常(不正常)<基础版>
1 异常分类
所有类中最大:Object
异常中最大类:Throwable(2类)
- Error 错误
- Exception 异常
- 运行时异常:/by zero-------不影响程序运行
- 非运行时异常:报错的地方(红线)------编辑代码过程中:调用某方法时,可能会出现异常
编码中,只要有一个报错的地方(红线),代码就不能运行
异常发生背景 | 没有按正常的步骤执行完毕 | 未点退出,直接闪退 |
---|---|---|
异常 | 自己可以解决 | 其他人登录,改密码,重新登录 |
错误 | 不可以解决 | 服务器瘫痪,后台调整 |
2 解决异常(2种)
2.1 捕获异常 try catch finally-----拿到异常对象后,做什么(类比if else)
2.1.1 try --------可能发生异常的所有相关的代码
try{
可能发生异常的代码
如果发生异常,(虚拟机自动 按catch异常类型 创建异常对象)并被抛出
try:放可能发生异常的所有相关的代码
1.(自身)放可能发生异常的代码
2.(关联)可能发生异常代码的返回值------输出System.out.println();
try代码块中:A处发生异常,A处以下的内容都不会执行。即:不会输出后续错误的数据,比如System.out.println()在try代码块下方,此时打印内容就为错误。
try 直达 finally | try catch1 finally | try catch2 finally |
---|---|---|
手抓饭 | 用勺子吃饭 | 用筷子吃饭 |
最简洁情况 | 额外处理:勺子的逻辑: 从哪获得 怎么用等 | 额外处理:筷子的逻辑: 从哪获得 怎么用等 |
2.1.2 catch --------多分支多捕获
}catch(异常类型1 变量名){捕获异常对象,给变量赋值
catch代码块中的代码 只在异常发生时 执行
异常对象调用方法
异常变量名.printStackTrace();-----------打印异常相关信息/执行特定代码
return XXX;
}catch(异常类型2 变量名){
1个try可搭配多个catch。
可以并列多个不同类型异常,捕获同一块try代码不同异常类型对象
因为代码从上而下执行,必须:
捕获异常顺序:子类异常在上,父类异常在下----每次异常发生,只执行一个catch块
- 小异常类型catch放上面
- 或者,只用一个最大的异常类型接受
错误:
try{
}catch(Exception e){ -----异常已经被Exception捕获
}catch(ParseException e){} ----错误
正确:
try{
}catch(ParseException e){}
}catch(Exception e){
2.1.3 finally----必须执行、return位置
}finally{
无论正常还是异常都必须执行
}
return :代码块中最后一句执行的代码==return后有代码也不会执行
- 异常:try catch finally 输出顺序:try catch finally catch的return
- 正常:try catch finally try的return
- finally中写返回值==try和catch中return都作废(都return,但finally的return是最终的)
2.2 异常相关信息—看出哪里错(会看异常debug)
- 不会一次性把所有出错地方报出,只能按代码从上到下执行逻辑,碰到第一个报一个,解决完这个才能继续执行下面内容,看到下一个。
- 只报出一个错,不代表后面都没错。
2.2.1 定 异常的类型?
ArithmeticException:运算异常--------思考:自己写的代码哪里运算了
2.2.1 定 空间位置?
- 不要看:别人定义的类
1.提供给我们使用,别人定义好的类,不会有错。
2.自己改不了别人类
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at org.springframework.web.servlet.FrameworkServlet.service
at java.lang.Thread.run
报别人类的异常 原因:自己写的代码触发到别人定义的类的报错信息,找错要在自己类中找
java.lang.Thread.run :java API里面的类,相关信息报错
API=接口:java实现很多功能,把功能封装到一个接口。把java的lib包下载下来,自己类实现java接口==本地和java联通接口,就能调用里面的类和类的方法
- 只看自己定义的类:异常信息中找自己写的包(com.公司名.项目名)下的自己定义的类
at com.wy.controller.UmsUserController.page(UmsUserController.java:35)
at(在)com.wy.controller(包下).UmsUserController(类下).page(方法中)
(UmsUserController.java:35) :(类名.java文件:35行)
:在类名UmsUserController的java文件中第35行报错(直接原因报错/间接原因)可直接定位
- 直接原因:该行错误
- 间接原因:报错的位置只是打印输出------思考:看上边代码,有关打印内容如何产生的代码(关联代码)
2.2 抛异常 throws ------告知调用方法的人,方法有异常
2.2.1 抛出异常声明(异常类型)------一个大范围异常类型
Add exception to method signature
添加异常到方法声明处==到(可能发生异常的代码 所在的方法的)方法声明处添加异常声明
public static void main(String[] args)throws ParseException(){}
谁执行这个方法,谁处理异常。
自定义方法,异常------抛给main方法-----虚拟机执行main方法,虚拟机jvm不能解决异常只能抛出==异常轨迹打印到控制台,告知程序员出错
- throws 向外抛出大范围的异常即可。 ==可以写多个异常类型,顺序不影响执行,但是默认只执行最大范围的异常类型。
- 同级异常类型,并列即可。会随情况被调用
2.2.1方法构成(2部分)
public static void main() ----(1)方法声明
{} ----(2)方法体(方法内容)
2.2.3 try 与 throws 异同
try | throws |
---|---|
捕获:异常对象 | 抛出:异常声明(异常类型) |
方法体内部 | 方法声明处 |
捕获异常类型顺序: 子上父下 | 异常类型没有父子顺序,但是默认父接受 (一般只写一个最大异常类型) |
掐灭火种: 主动抓住异常对象 | 纸包不住火: 层层推卸责任,最终到jvm,打印异常 |
共性:都没解决异常。
2.2.3 设置:自定义方法报红(错误提示)
谁调用这个(有问题的方法),就给谁报红-------强制(try catch 或者 抛出)
public static void test1()throws Exception(){}
方法声明处添加异常声明: 非运行时异常。
运行时异常,是不会在调用(有问题的方法)时候报红的。(只有运行时,才能被识别)
3 throw 向外抛出异常对象
应用场景
自定义异常类(继承Exception)----报错提示:throw抛出-----解决异常:try catch 捕获/throws 抛出
new MyException()
不向外抛出,是不会有报红提示的(即也没有后续try catch、throws)
public class MyException extends Exception{}
【解决1:【抛出】
public static void test1 throws Exception{
throw new MyException(); ------报红提示
}
【解决2:【捕获】
public static void test1{
try{throw new MyException(); ------报红提示
}catch(Exception e ){e.printStackTrace();}
4 异常/by zero
错因:除法运算中,除数为0导致(分母不能为0)
java.lang.ArithmeticException(运算异常): / by zero