异常类型
public class Exception01
{
public static void main(String[] args)
{
int num1 = 10;
int num2 = 0;//Scanner();
//1. num1 / num2 => 10 / 0
//2. 当执行到 num1 / num2 因为 num2 = 0, 程序就会出现(抛出)异常 ArithmeticException
//3. 当抛出异常后,程序就退出,崩溃了 , 下面的代码就不在执行
//4. 大家想想这样的程序好吗? 不好,不应该出现了一个不算致命的问题,就导致整个系统崩溃
//5. java 设计者,提供了一个叫 异常处理机制来解决该问题
//int res=num1/num2;
//如果程序员,认为一段代码可能出现异常/问题,可以使用 try-catch 异常处理机制来解决
//从而保证程序的健壮性
//将该代码块->选中->快捷键 ctrl + alt + t -> 选中 try-catch
//6. 如果进行异常处理,那么即使出现了异常,程序可以继续执行
try {
int res = num1 / num2;
} catch (Exception e) {
//e.printStackTrace();
System.out.println("出现异常的原因=" + e.getMessage());//输出异常信息
}
System.out.println("程序继续运行....");
}
}
public class Exception01 { public static void main(String[] args) { int num1 = 10; int num2 = 0;//Scanner(); //1. num1 / num2 => 10 / 0 //2. 当执行到 num1 / num2 因为 num2 = 0, 程序就会出现(抛出)异常 ArithmeticException //3. 当抛出异常后,程序就退出,崩溃了 , 下面的代码就不在执行 //4. 大家想想这样的程序好吗? 不好,不应该出现了一个不算致命的问题,就导致整个系统崩溃 //5. java 设计者,提供了一个叫 异常处理机制来解决该问题 //int res=num1/num2; //如果程序员,认为一段代码可能出现异常/问题,可以使用 try-catch 异常处理机制来解决 //从而保证程序的健壮性 //将该代码块->选中->快捷键 ctrl + alt + t -> 选中 try-catch //6. 如果进行异常处理,那么即使出现了异常,程序可以继续执行 try { int res = num1 / num2; } catch (Exception e) { //e.printStackTrace(); System.out.println("出现异常的原因=" + e.getMessage());//输出异常信息 } System.out.println("程序继续运行...."); } } |
基本概念:
Java语言中,将程序执行中发生的不正常的情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)
执行过程中所发生的异常事件可分为两类:
1.Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误,资源耗尽等严重情况(StackOverflowError【栈溢出】和OOM【outof memory】 Error是严重错误,程序会崩溃。
2.Exception: 其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等,
Exception分为两大类:运行时异常【程序运行时发生的异常】和编译时异常【编程时,编译器检查出的异常】
1.对于编译异常,程序中必须处理,比如try—catch或者throws
2.对于运行时异常,程序中如果没有处理,默认就是throws的方式处理
常见的运行时异常包括
1)NullPointerException 空指针异常
public class NullPointerException_ { public static void main(String[] args) { String name = null; System.out.println(name.length()); } } |
2)ArithmeticException 数学运算异常
3)ArrayIndexOutOfBoundsException 数组下标越界异常
public class ArrayIndexOutOfBoundsException_ { public static void main(String[] args) { int[] arr = {1,2,4}; for (int i = 0; i <= arr.length; i++) { System.out.println(arr[i]); } } } |
4)ClassCastException 类型转换异常
public class ClassCastException_ { public static void main(String[] args) { A b = new B(); //向上转型 B b2 = (B)b;//向下转型,这里是 OK C c2 = (C)b;//这里抛出 ClassCastException } } class A {} class B extends A {} class C extends A {} |
5)NumberFormatException 数字格式不正确异常[]
public class NumberFormatException_ { public static void main(String[] args) { //String name = "1234"; String name = "韩顺平教育"; //将 String 转成 int int num = Integer.parseInt(name);//抛出 NumberFormatException System.out.println(num);//1234 } } |
常见的编译时异常包括:
1.SQLException //操作数据库时,查询表可能发生异常
2.IOException //操作文件时发生的异常
3.FileNotFoundException //当操作一个不存在的文件时,发生异常
4.ClassNotFoundExceptiom //加载类,而类不存在,发生异常
5.EofException //操作文件到文件末尾,发生异常
6.lllegalArguementException //参数异常
异常处理方式:
1.try-catch-finally
程序员在代码中捕获发生的异常
![](https://i-blog.csdnimg.cn/blog_migrate/9d35c42f6459fd46584dedb01d92b221.png)
处理细节:
1.如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块
2.如果异常没有发生,则顺序执行try的代码块,不会进入到catch
3.如果希望不管异常有没有发生,都执行某段代码(比如关闭连接,释放资源等)则使用try—catch—finally
public class TryCatchDetail { public static void main(String[] args) { //ctrl + atl + t //老韩解读 //1. 如果异常发生了,则异常发生后面的代码不会执行,直接进入到 catch 块 //2. 如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch //3. 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码- finally try { String str = "韩顺平"; int a = Integer.parseInt(str); //发生异常跳出到catch System.out.println("数字:" + a); //不执行 } catch (NumberFormatException e) { System.out.println("异常信息=" + e.getMessage()); } finally { System.out.println("finally 代码块被执行..."); } System.out.println("程序继续..."); } } |
4.可以有多个catch语句捕获不同的异常,要求子类异常在前,父类异常在后,(比如:NullPointerException在前,Exception在后),如果发生异常,只会匹配一个catch
public class TryCatchDetail02 { public static void main(String[] args) { //老韩解读 //1.如果 try 代码块有可能有多个异常 //2.可以使用多个 catch 分别捕获不同的异常(只是对不同异常进行处理,只能捕获第一个异常,) //3.要求子类异常写在前面,父类异常写在后面 try { Person person = new Person(); //person = null; System.out.println(person.getName());//NullPointerException int n1 = 10; int n2 = 0; int res = n1 / n2;//ArithmeticException } catch (NullPointerException e) { System.out.println("空指针异常=" + e.getMessage()); } catch (ArithmeticException e) { System.out.println("算术异常=" + e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); } finally {} } } class Person { private String name = "jack"; public String getName() { return name; } } |
5.可以进行try-finally配合使用,这种用法相当于没有捕获异常,因此程序会因此程序会直接崩掉/退出。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑
public class TryCatchDetail03 { public static void main(String[] args) { /* 可以进行 try-finally 配合使用, 这种用法相当于没有捕获异常, 因此程序会直接崩掉/退出。应用场景,就是执行一段代码,不管是否发生异常, 都必须执行某个业务逻辑 */ try { int n1 = 10; int n2 = 0; System.out.println(n1 / n2); } finally { System.out.println("执行了 finally.."); //因为没有catch,执行完后崩溃,相当于throws } System.out.println("程序继续执行.."); //不执行 } } |
2.throws
将发生的异常抛出,交给调用者(方法)处理,最顶级的处理者是jvm
![](https://i-blog.csdnimg.cn/blog_migrate/c7f4cbc61e85e8053ad2b5cdaa59eb09.png)
基本介绍:
1.如果一个方法中的语句执行时可能产生某种异常,但是不确定如何处理这种异常,则此方法应显示的声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理
2.在方法生命中用throws语句可以声明抛出异常列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
Public static void readFile(String file) throws FileNotFoundException,Exception { FilenputStream fis=new FilenputStream("d://aa.txt"); //读文件时产生异常 }
|
处理细节:
1.对于编译异常,程序中必须处理,比如try—catch或者throws
2.对于运行时异常,程序中如果没有处理,默认就是throws的方式处理
3.子类重写父类方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出异常的类型的子类型
4.在throws过程中,如果有方法try—catch,就相当于处理异常,就不必throws
public class ThrowsDetail { public static void main(String[] args) { f2(); } public static void f2() /*throws ArithmeticException*/ { //1.对于编译异常,程序中必须处理,比如 try-catch 或者 throws //2.对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理 int n1 = 10; int n2 = 0; double res = n1 / n2; } public static void f1() //throws FileNotFoundException { //这里大家思考问题 调用 f3() 报错 //老韩解读 //1. 因为 f3() 方法抛出的是一个编译异常 //2. 即这时,就要 f1() 必须处理这个编译异常 //3. 在 f1() 中,要么 try-catch-finally ,或者继续 throws 这个编译异常 f3(); // 抛出异常 } public static void f3() throws FileNotFoundException { FileInputStream fis = new FileInputStream("d://aa.txt"); } public static void f4() { //1. 在 f4()中调用方法 f5() 是 OK //2. 原因是 f5() 抛出的是运行异常 //3. 而 java 中,并不要求程序员显示处理,因为有默认处理机制 f5(); } public static void f5() throws ArithmeticException { } //public static void f5() throws FileNotFoundException { } f4()中的f5()会报错 } class Father { public void method() throws RuntimeException { } } class Son extends Father { //3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法, //所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型 //4. 在 throws 过程中,如果有方法 try-catch , 就相当于处理异常,就可以不必 throws @Override public void method() throws ArithmeticException { } } |
自定义异常
当程序中出现了某些“错误”,但该错误信息没有在Throwable子类中描述处理,这个时候可以自己设计异常类,用于描述错误信息。
自定义异常步骤:
1.定义义异常类名(程序员自己写)继承Exception(编译异常)或者RuntimeException(运行异常)
2.一般情况下,我们自定义异常是继承RuntimeException ,即把自定义异常做成运行时异常,好处是,我们可以使用默认的处理机制
public class CustomException { public static void main(String[] args) /*throws AgeException*/ { int age = 180; //要求范围在 18 – 120 之间,否则抛出一个自定义异常 if(!(age >= 18 && age <= 120)) { //这里我们可以通过构造器,设置信息 throw new AgeException("年龄需要在 18~120 之间"); } System.out.println("你的年龄范围正确."); } } class AgeException extends RuntimeException { public AgeException(String message) //构造器 { super(message); } } |
![](https://i-blog.csdnimg.cn/blog_migrate/5ad6dfa97332e34b986c45ea2f3ad589.png)