一般异常代码:
public class Exception01 { public static void main(String[] args) { int n1 = 10; int n2 = 0; // n1 / n2 => 10 / 0 int res = n1/n2; System.out.println("程序继续运行……"); } }
设置了异常捕获(try-catch):
public class Exception01 { public static void main(String[] args) { try{ int n1 = 10; int n2 = 0; // n1 / n2 => 10 / 0 int res = n1/n2; } catch (Exception e){ // TODO:handle exception //e.printStackTrace();//打印异常堆栈,即将异常出错的代码和信息输出 System.out.println("异常信息=" + e.getMessage()); } System.out.println("程序继续运行……"); } }
Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法
错误和逻辑错误不是异常)
类关系图:
NullPointerException空指针异常
String name = null; System.out.println(name.length());
ArithmeticException数学运算异常
int n1 = 10; int n2 = 0; int res = n1/n2;
ArrayIndexOutOfBoundsException数组下标越界异常
int[] arr = {1, 2, 4}; for (int i = 0; i <= arr.length; i++) { System.out.println(arr[i]); }
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 B {}
NumberFormatException数字格式不正确异常
String name = "Jack"; //将 String 解析成 int int num = Integer.parseInt(name);
异常处理就是当异常发生时,对异常处理的方式。
try{ //代码/可能有异常 } catch (Exception e) { //捕获异常 //1.当异常发生时 //2.系统将异常封装成Exception对象e,,传递给catch //3.得到异常对象后,程序员自己处理 } finally { //没有finally语法也是可以通过的 //不管有没有异常,finally一定要执行 }
异常默认使用throws。
直接使用try-finally进行配合,相当于没有捕获异常,因此程序会直接崩溃。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑。
try{ //代码...... } finally { //总是执行的代码 }
使用ctrl + alt + t
快捷键设置try-catch
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7aIbVacn-1644128312071)(.\image\image-20211007084308512.png)]
public class TryCatch01 { public static void main(String[] args) { try { String str = "Jack"; int a = Integer.parseInt(str); System.out.println("数字:" + a); } catch (NumberFormatException e) { System.out.println("异常信息 = " + e.getMessage()); } System.out.println("程序继续......"); } }
如果希望不管发生什么都执行某段代码,则使用finally。
可以有多个 catch语句,捕获不同的异常进行不同的业务处理),要求父类异常在后,子类异常在前,比如( Exception在后, NullPointerException在前),如果发生异常,只会匹配一个 catch。
public class TryCatchDetail02 { public static void main(String[] args) { 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 (Exception e) { System.out.println(e.getMessage()); } finally { } } } class Person{ private String name; public String getName() { return name; } }
改进后的多异常处理:
子类异常必须放在前面!!!
public class TryCatchDetail02 { public static void main(String[] args) { 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; public String getName() { return name; } }
public class TryCatchDetail03 { public static void main(String[] args) { try{ int n1 = 10; int n2 = 0; System.out.println(n1 / n2); } finally { System.out.println("执行了finally..."); } //不会继续运行,程序运行完finally后直接崩溃 System.out.println("程序继续运行..."); } }
public class TryCatchExercise01 { public static int method(){ try{ String[] names = new String[3]; if(names[1].equals("tom")){//NullPointerException System.out.println(names[1]); } else{ names[3] = "hspedu"; } return 1; } catch (ArrayIndexOutOfBoundsException e){ return 2; } catch (NullPointerException e){ return 3; } //由于finally必须执行,则一定返回4 finally{ return 4; } } public static void main(String[] args) { System.out.println(method()); } }
public class TryCatchExercise02 { public static int method(){ int i = 1; try{ i++;//2 String[] names = new String[3]; if(names[1].equals("tom")){//NullPointerException System.out.println(names[1]); } else{ names[3] = "hspedu"; } return 1; } catch (ArrayIndexOutOfBoundsException e){ return 2; } catch (NullPointerException e){ return ++i;//3 } //由于finally必须执行,则一定返回4 finally{ return ++i;//4 } } public static void main(String[] args) { System.out.println(method());//4 } }
public class TryCatchExercise03 { public static int method(){ int i = 1;//1 try{ i++;//2 String[] names = new String[3]; if(names[1].equals("tom")){//NullPointerException System.out.println(names[1]); } else{ names[3] = "hspedu"; } return 1; } catch (ArrayIndexOutOfBoundsException e){ return 2; } catch (NullPointerException e){ //返回3 return ++i;//3 } finally{ ++i;//4 System.out.println("i = " + i);//i = 4 } } public static void main(String[] args) { System.out.println(method());//3 } }
public class TryCatchExercise04 { /* 1.创建Scanner * 2.使用无限循环去接受一个输入 * 3.然后将输入的值转化为int * 4.如果在转化时抛出异常,则说明输入内容不能转化为int * 5.如果没有抛出,则break该循环*/ public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int num = 0; while (true) { System.out.println("请输入一个整数:\n"); try { num = Integer.parseInt(scanner.next()); break; } catch (NumberFormatException e) { System.out.println("输入有误,请重新输入!\n"); } } System.out.printf("您的输入为: " + num); } }
如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对异常进行处理。
在方法中使用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
public class Throws01 { public static void main(String[] args) { } //public void f1() throws Exception 也可以 public void f1() throws FileNotFoundException, NullPointerException { //创建了一个文件流对象 //这里的异常是一个FileNotFoundException //可以使用try-catch //也可以使用throws,抛出异常,让调用fi方法的调用者()处理 //throws关键字后也可以是列表 FileInputStream fis = new FileInputStream("dd.txt"); } }
对于编译异常,程序中必须处理,比如try-catch或者throws
对于运行时异常,程序中如果没有处理,默认是throws的方法处理
子类重写父类的方法时,对抛出异常的规定:子类重写的方法所抛出的异常类型要么和父类抛出的一致,要么为父类抛出异常类型的子类型。
class Father { public void method() throws RuntimeException{ } } class Son extends Father { //子类重写父类的方法时,对抛出异常的规定: // 子类重写的方法所抛出的异常类型要么和父类抛出的一致, // 要么为父类抛出异常类型的子类型。 @Override public void method() throws NullPointerException { } }
解决方法1:使用try-catch处理
解决方法2:throws抛出
当程序中出现了某些“错误”,但该错误没有在Throwable子类中描述处理,这个时候可以自己设计异常类,用于描述错误信息。
Expection
或RnntimeExpection
Expection
,属于编译异常RuntimeExpection
,属于运行异常(一般继承RuntimeExpection
)public class CustomExpection { public static void main(String[] args) { int age = 800; //要求年龄在18-120之间1,否则抛出一个异常 if (!(age >= 18 && age <= 120)) { throw new AgeException("年龄需要在18~120之间!"); } System.out.println("你的年龄范围正确!"); } } //自定义的一个异常 //1.一般情况,自定义异常都是继承RuntimeException,即运行时异常 //2.好处是,我们可以使用默认的处理机制 class AgeException extends RuntimeException { //构造器 public AgeException(String message) { super(message); } }
意义 | 位置 | 后面跟的东西 | |
---|---|---|---|
throws | 异常处理的一种方式 | 方法声明处 | 异常类型 |
throws | 手动生成异常对象的关键字 | 方法体中 | 异常对象 |