在Java中,异常是指在程序运行过程中发生的错误或异常情况。Java提供了一套异常处理机制,可以帮助开发者更好地管理和处理异常。 一、异常的分类 Java中的异常分为两大类:Checked异常和Unchecked异常。 1. Checked异常(受检异常):Checked异常是在编译期间检查的异常,继承自Exception类。当一个方法可能引发一个Checked异常时,方法必须通过throws关键字声明这个异常,或者在方法内部使用try-catch块处理这个异常。 2. Unchecked异常(非受检异常):Unchecked异常是在运行时检测的异常,继承自RuntimeException类。这种异常可以是程序错误或其他无法预测的异常情况。 二、常见的异常类及其用途 1. NullPointerException(空指针异常):当访问一个空对象的属性或调用空对象的方法时,抛出该异常。 2. ArrayIndexOutOfBoundsException(数组越界异常):当访问数组时索引超出数组范围时,抛出该异常。 3. ClassCastException(类转换异常):当试图将一个对象强制转换为不是其子类的类型时,抛出该异常。 4. IllegalArgumentException(非法参数异常):当传递给方法的参数不符合方法要求时,抛出该异常。 5. ArithmeticException(算术异常):当进行非法的算术运算时,例如除数为0,抛出该异常。 6. IOException(输入输出异常):处理输入输出操作时可能发生的异常,例如文件读写操作。 7. SQLException(SQL异常):处理与数据库相关的异常。 三、异常处理机制 Java提供了三种异常处理机制:try-catch-finally、throws和throw。 1. try-catch-finally:通过try-catch语句块可以捕获和处理异常。当try代码块中发生异常时,会跳转到对应的catch块进行处理。finally块中的代码无论是否发生异常都会被执行。 2. throws:用于在方法签名中声明一个可能抛出的异常,将异常的处理责任交给调用者处理。 3. throw:用于人为地抛出一个异常,可以在自定义方法中使用。 异常处理的目的是为了保证程序能够正常运行并提供相应的错误信息,避免程序崩溃。在实际开发中,需要根据不同的异常类型选择相应的异常处理策略,并适时记录异常信息以便进行排查和修复。 package lesson15; /** *java异常的父类是Throwable, Throwable有两个子类一个是Error,一个是Exception * *Error表示错误:是程序无法解决的问题,不是由程序员导致的,是很严重的问题 *Exception表示异常:是由程序员导致的问题,是小的错误,通过调程序可以解决 * *Exception有分为两种,一个是检查性异常,另一个是非检查性异常 *检查性异常:代码写出来就会直接报错,需要提前进行预处理 范围:RuntimeException及其子类以外的其他类 *非检查性异常:代码写出来不会报错,但是会在运行时报错。 范围:RuntimeException及其子类 处理异常的方式有三种1.声明异常。2.捕获异常。3.抛出异常。 */ public class ExceptionTest02 { //检查时异常 public void method() throws ClassNotFoundException { Class.forName("lesson15.ExceptionTest02"); } }
异常是在程序执行过程中遇到的错误或意外情况。下面列举并简要介绍几种常见的异常: 1. IndexError(索引错误):当访问序列(如列表、字符串)时使用了不存在的索引,或者索引超出了序列的范围,就会抛出该异常。 2. KeyError(键错误):当访问字典中不存在的键时,就会抛出该异常。 3. TypeError(类型错误):当操作或函数应用于不兼容的对象类型时,就会抛出该异常。例如,尝试对整数和字符串进行相加。 4. ValueError(数值错误):当传递给函数的参数无效或不合理时,就会抛出该异常。例如,尝试将字符串转换为数字时遇到非法字符。 5. FileNotFoundError(文件未找到错误):当尝试打开或读取不存在的文件时,就会抛出该异常。 6. ImportError(导入错误):当导入模块时发生错误,例如找不到模块或模块中不存在指定的属性时,就会抛出该异常。 7. ZeroDivisionError(零除错误):当试图除以零时,就会抛出该异常。 8. IOError(输入/输出错误):在读取或写入文件、网络连接等操作时发生错误时,就会抛出该异常。 9. AttributeError(属性错误):当访问对象中不存在的属性时,就会抛出该异常。 10. KeyboardInterrupt(键盘中断):当用户在程序运行过程中按下中断键(通常是Ctrl+C)时,就会抛出该异常。 以上是一些常见的异常类型,当然还有其他很多种异常。在编写程序时,可以通过捕捉这些异常并进行相应的处理来增加程序的健壮性和用户体验。 package lesson15; public class ExceptionTest03 { //throws声明异常 //异常发生时使用声明会将异常抛给主调方法,如果主调方法还不处理异常会继续向上抛 //直到到了main方法,如果还不处理就会发生宕机,程序停止运行。如果其中使用了catch //处理异常,那么后续调用就不会再发生异常了 public void method1() throws ClassNotFoundException { Class.forName("lesson15.ExceptionTest03"); } public void method2()throws ClassNotFoundException{ method1(); } public void method3(){ try { method2(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public void method4(){ method3(); } public static void main(String[] args) { } }
try代码块是一种异常处理机制,用于捕获可能出现的异常并执行相应的处理逻辑。try代码块的语法结构如下: ``` try { // 可能会抛出异常的代码 } catch (异常类型1 变量名1) { // 当抛出异常类型1时执行的处理逻辑 } catch (异常类型2 变量名2) { // 当抛出异常类型2时执行的处理逻辑 } finally { // 不管是否发生异常,都会执行的代码 } ``` 当程序执行到try代码块时,会按照顺序依次执行代码块内的语句。如果在try代码块中抛出了异常,程序会立即跳转到catch代码块中,并且根据抛出的异常类型选择执行相应的处理逻辑。如果try代码块没有抛出异常,catch代码块将被跳过。 finally代码块是可选的,不管try代码块中是否发生异常,finally代码块中的语句都会被执行。通常在finally代码块中进行资源的释放和清理操作,比如关闭文件和数据库连接。 通过使用try代码块,我们可以捕获并处理程序中可能出现的异常,从而增加程序的健壮性和容错性。 package lesson15; /** * 面试题:final finally finalize的区别 * final可以修饰变量,方法和类,修饰的类没有子类,修饰的方法不能被重写,修饰的变量就是常量 * finally是异常中跟try配套的,无论try中是否发生异常都会执行finally中的代码 * finalize在垃圾器执行的时候如果代码中有finalize方法,就会在本次回收对象的时候放过该对象,下次在回收 */ public class ExceptionTest04 { public static void main(String[] args) { int a[] = new int[10]; //try代码块中写的是可能发生异常的代码 try{ //try不能单独存在 System.out.println(a[10]); System.out.println("try代码块执行了"); }//零个或多个都可以 catch (ArrayIndexOutOfBoundsException e){ //catch代码块中写的是处理异常的代码 System.out.println("数组越界"); }catch (RuntimeException e){ //catch后面还可以跟很多个catch }catch (Exception e){ //父异常不能写在子异常前面 } //跟0个或1个 finally{ //不管代码是否发生异常,finally中代码都会执行 //finally代码块中写的是受保护(一定要执行)的代码 System.out.println("finally代码了"); } } }
数组越界是指访问数组时,索引值超过了数组的范围。当我们尝试访问一个不存在的数组元素时,会出现数组越界错误。例如,如果一个数组的长度为N,而我们尝试访问索引为N或大于N的元素,就会导致数组越界。
数据溢出是指计算过程中,数据的大小超过了其所能表示的范围。在计算机中,每种数据类型都有其表示范围,当一个变量的值超过了这个范围,就会发生数据溢出。例如,如果一个整数类型的变量的值超过了其表示的最大值,就会导致数据溢出。
数组越界和数据溢出都是非常常见的编程错误,会导致程序出现未定义的行为或崩溃。为了避免这些错误,我们应该在编写代码时注意边界条件的判断,确保数组的索引在合法范围内,并且对于可能导致溢出的计算操作,要进行合理的处理,避免数据溢出的发生。
package lesson15; /** * 面试题:写出五个你积累的异常 * Exception ArrayIndexOutOfBoundsException NullPointerException IOException * RuntimeException */ //自定义异常要先继承Exception public class ExceptionTest05 extends Exception{ public ExceptionTest05(){ super("数组下标越界,请检查自己的代码"); } public static void main(String[] args) throws ExceptionTest05 { try{ int []a = new int [5]; System.out.println(a[5]); }catch (ArrayIndexOutOfBoundsException e){ //抛出的同时要在方法上声明异常否则编译报错 throw new ExceptionTest05(); } } }