异常的体系
他们之间的继承体系
Throwable//抛出 能力
-> Exception(编译)->RunnTimeException(运行) //运行中出现逻辑问题可以处理
->Error //虚拟机出现了问题
我们需要处理的异常只有Exception和Runnable其他的异常(虚拟机异常)我们处理不了也不能处理
如果程序中出现了异常或者可能出现的我们不处理,那么当异常出现的时候此时程序将不会继续运行,如果处理就可以继续运行了
处理异常的方法
当异常出现的时候我们有两种方法处理他
1:try()catch{}finaly{}处理
我们接下来演示一下出现异常的情况和处理方法
我们直接演示多个catch和finally
我们用try捕获异常,然后将异常转为一个对象在catch的形式参数内
然后再cath进行处理
finally就是无论如何都可以执行的语句
try必须和catch/finally或一起在一起 不能分开 分开什么都不是
//此表表示0不能为除数的算数异常
//java.lang.ArithmeticException表示异常类型
//下边最后一行就是出现异常的地方CatchDemo.java:5
//倒数第二行表示 根本原因为第8行CatchDemo.java:8
//此时我们就可以考虑使用异常处理的方法来处理第八行的代码
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.xiaomi._01_trycatch.CatchDemo.divide(CatchDemo.java:8)
at com.xiaomi._01_trycatch.CatchDemo.main(CatchDemo.java:5)
演示try catch
public static int sum(int a,int b){
//如果当a==0的时候那么就会出现异常怎么办
try(
//放可能出现的异常的代码 并且捕获
return a/b;
)catch(ArithmeticException e){ //可能出现的异常的类型拿到他对象
//此处可以处理异常 可以获取到异常对象中封装的异常信息
System.out.println("除法运算数有错误");
System.out.println(e.getMessage() //获取异常信息
e.printStackTrace(); //打印异常所有的信息
}catch(NumberFormatException e){
System.out.println("除法运算数有错误");
e.printStackTrace();
}finally{
//无论如何都会执行的代码
System.out.println("无论如何都都会执行的代码");
}
return -1;
}
-----------------------------------
注意
1:e.printStackTrace(); //catch 必须有这一行代码
2:当出现多种异常的时候 以先后顺序出现 但是不会一起出现 只有当你解决了一个异常之后才会出现第二个异常
3:小细节: catch越上边要越小 越底下要越大 因为大的类型接收之后底下的小的类型就没有任何作用
4:无论程序是否有异常fially都会执行 可以把必须要执行的代码放到这里
一般我们把退出或者或者结束的代码放在这里面 如果前边有System.exist()
那么久不行了 程序都结束了就不存在执不执行的问题了
2:可能出现异常的地方throws他(提醒)
作用:在可能出现异常的方法上声明可能出现的异常类型提醒调用者处理异常
抛出异常的原因:该方法自身处理不了该异常,只能使用throws提醒该方法的调用者需要处理异常。当然调用者也有两种处理方式: 自己捕获处理或再次抛出
//代码就不演示了 演示一下在哪里抛出 然后告诉调用者出现了异常类型A和异常类型B 让调用者处理
public static void divide(int a,int b)thrwos 异常类型A,异常类型B.......{
System.out.println(a / b);
}
//抛出之后就在调用者那里处理
//如果调用者不处理就继续抛出
//最终会抛给JVM虚拟机然后JVM只能也只会终止程序
3:throw 处理他
作用:当一个方法内,需要返回一个错误结果给调用者,用throws
其实throws的用法就是,当一段代码有可能出现异常的时候,那么此时你就有且可以使用throw’s抛给调用者让他们知道自己在哪里填写错误这个样
public static int sum(int a,int b){
//演示一下抛出错误的演示就可以了
public static boolean isExist(String userName) throws Exception{
String[] data = {"will","lucy"};//模拟已将注册的用户
if(UserName != null && userName.length()>0){
for(String name:date){
if(name.equals(userName)){//如果此时用户名存在就手动抛出一个异常就好
throw new Exception("用户名已经存在"+userName);
}
}
}
return false; //不能插入了
}
}
throw new Exception(“用户名已经存在”+userName); //此行代码会结束当前方法并返回异常和问题
自定义异常
标记一下重点
RunTimeException:运行时异常,又称不受检查异常,不受检查!
不受检查!!不受检查!!!重要的事情说三遍,因为不受检查,所以在代码中可能会有RunTimeException时Java编译检查时不会告诉你有这个异常,但是在实际运行代码时则会暴露出来,比如经典的1/0,空指针等。如果不处理也会被Java自己处理。
作用:当我们出现一些没有定义的错误的是或逻辑异常此时就需要我们自己创建异常了
//创建自定义异常有两种方法 Exception(编译异常)和RunnableException(运行异常)我们一般都继承RunnalbeException
//新版本带解释
1:定义一个异常 继承于Exception的异常
public class CustomerLogicException extends Exception{
public CustomerLogicException(){}
//message时Throwable 类中的字段
public CustomerLogicException(String message){
super(message);
}
}
2://定义一个客户类
public class LogicException{
public static void main(String[] args){
try{
addCustomer(){};
}catch(CustomerLogicException e){
e.printStackTrace();
}
System.out.println("end...")
}
//添加一个客户方法
public static void addCustomer() throws CustomerLogicException{
//添加客户的过程,需要检查客户的相关信息
//如果检查失败,那么就抛出异常
//通过String类型参数的构造器
throw new CustomerLogicException("客户信息错误");
}
}
//
1:自定义创建了一个异常类 继承于Exception
2:创建另一个LogicExceptionlei
3:添加一个客户方法抛出自定义异常
4:在主方法里面处理异常就好 (主方法里面不建议抛出异常了 没用)
//老版本带解释
---------------------------------------------------------
自定义的异常类
语法
public class CustomerException extends RunTimeException(){
//错误中可以添加自定义的属性,代表这个错误是针对哪个客户产生的。
private Customer customer;
public CustomerException(String message,Customer customer){
super(message); //这个点千万不能忘记,,表示把传递的异常信息存储倒异常对象中
this.customer = customer;
}
}
-----------------------------------------------------------
//客户类
public class Customer {
String name;
public Customer(String name) {
this.name = name;
}
}
-----------------------------------------------------------
//最后测试
public class Exception{
//定义一个方法模拟用户在操作软件的时候出现了相关的逻辑错误
public static boolean someCustomerLogic(String name){
Customer c = new Customer(name);
//....过了很久
//此时代表上边自定义的异常 然后有一个构造器 可以定义一个String 和一个 类名
throw new CustomerException("客户逻辑错误",new Customer(name));
}
//这里就是走了一个主方法
//然后捕获了那个异常 又把捕获的对象强制转换上边自定义异常的类型
//然后用自定义异常的类型的方法获取了这出现错误的对象
......
public static void main(String[] args) {
try {
someCustomerLogic("will");
} catch (Exception e) {
//通过判断错误的类型,可以把错误强行转成CustomerException
if (e instanceof CustomerException) {
CustomerException ce = (CustomerException) e;
System.out.println(ce.customer);//就可以得到错误中的客户对象了。
}
}
}
}