14.1 概念
在日常编码中或多或少都会现一些问题,这些问题有的是错误和有的是异常(不正常)。
日常编码这种问题分为两类:
1、错误 Error
2、异常 Exception
错误在jvm,硬件层面报出的问题
异常是代码运行层面
bug:
1、编码语法错误(很好解决)
2、运行时异常 这种异常也好解决,根据提示去做修改方案
3、运算结果没有达到预期结果。 这种问题需要去查看代码逻辑,断点调试,观察变量数据变化。
14.2 异常 :
Exception: 是所有异常种类的父类
RuntimeException : 运行时异常 可以不用人为的去处理,JVM会自动处理
检测性运行时异常: 必须要人为手工处理,不处理程序写不下去 。
14.3 RuntimeException
Java 根据各个类库也定义了一些其他的异常,下面的表中列出了 Java 的非检查性异常。
异常 | 描述 |
---|---|
ArithmeticException | 当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。 |
ArrayIndexOutOfBoundsException | 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。 |
ArrayStoreException | 试图将错误类型的对象存储到一个对象数组时抛出的异常。 |
ClassCastException | 当试图将对象强制转换为不是实例的子类时,抛出该异常。 |
IllegalArgumentException | 抛出的异常表明向方法传递了一个不合法或不正确的参数。 |
IllegalMonitorStateException | 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。 |
IllegalStateException | 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。 |
IllegalThreadStateException | 线程没有处于请求操作所要求的适当状态时抛出的异常。 |
IndexOutOfBoundsException | 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。 |
NegativeArraySizeException | 如果应用程序试图创建大小为负的数组,则抛出该异常。 |
NullPointerException | 当应用程序试图在需要对象的地方使用 null 时,抛出该异常 |
NumberFormatException | 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。 |
SecurityException | 由安全管理器抛出的异常,指示存在安全侵犯。 |
StringIndexOutOfBoundsException | 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。 |
UnsupportedOperationException | 当不支持请求的操作时,抛出该异常。 |
下面的表中列出了 Java 定义在 java.lang 包中的检查性异常类。
异常 | 描述 |
---|---|
ClassNotFoundException | 应用程序试图加载类时,找不到相应的类,抛出该异常。 |
CloneNotSupportedException | 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。 |
IllegalAccessException | 拒绝访问一个类的时候,抛出该异常。 |
InstantiationException | 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。 |
InterruptedException | 一个线程被另一个线程中断,抛出该异常。 |
NoSuchFieldException | 请求的变量不存在 |
NoSuchMethodException | 请求的方法不存在 |
14.4 异常处理
- 1、try{...}catch(Exception e){....}finally{...}结构 用于你觉得可能会出现异常的代码段。 try{正常的业务功能逻辑} catch(异常类 对象){写你对这个异常的处理}, 所以catch小括号中就是在定义一个异常类的对象,而catch代码块中就是用这个异常对象来处理异常
catch (InputMismatchException ex){
ex.getMessage(); //获取异常信息
ex.printStackTrace();//打印堆栈信息
}
catch可以写很多个,用于处理try中出现的不同种类的异常
代码语言:javascript复制try {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int n1 = input.nextInt();
System.out.println("请输入第二个数:");
int n2 = input.nextInt();
int result = n1 / n2;
System.out.println(result);
}catch (InputMismatchException ex){
ex.getMessage(); //获取异常信息
ex.printStackTrace();//打印堆栈信息
}catch(ArithmeticException ex){
ex.printStackTrace();
}catch (ArrayIndexOutOfBoundsException ex){
ex.printStackTrace();
}catch (NullPointerException ex){
ex.printStackTrace();
}
这种写法比较精准的去捕捉异常信息
代码语言:javascript复制try {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int n1 = input.nextInt();
System.out.println("请输入第二个数:");
int n2 = input.nextInt();
int result = n1 / n2;
System.out.println(result);
}catch (RuntimeException ex){
ex.getMessage(); //获取异常信息
ex.printStackTrace();//打印堆栈信息
}
System.out.println("程序结束");
这样可以捕捉所有的异常
finally{...}无论程序走不走catch最后都要执行finally中的代码
代码语言:javascript复制try {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int n1 = input.nextInt();
System.out.println("请输入第二个数:");
int n2 = input.nextInt();
int result = n1 / n2;
System.out.println(result);
}catch (RuntimeException ex){
ex.getMessage(); //获取异常信息
ex.printStackTrace();//打印堆栈信息
}finally {
System.out.println("程序结束");
}
try,catch,finally 可以怎么组合呢?
可以只写try...catch()...
也可以只写try....finally... 这样结构说白了就是没有的异常的捕捉
代码语言:javascript复制public static void main(String[] args) {
try {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int n1 = input.nextInt();
System.out.println("请输入第二个数:");
int n2 = input.nextInt();
int result = n1 / n2;
System.out.println(result);
}finally {
System.out.println("程序结束");
}
}
//以前出了异常程序后终断执行,现在出了异常程序也会终断执行,但是会先将finally中的代码执行完后再终断
不能没有try。
- 2、如果某个方法有异常的代码段我不处理这个异常,转交给调用处进行处理 语法 : public void 方法名() throws Exception(异常类名){ } 异常向外抛。
14.5 创建一个自定异常
创建一个自定异常也叫抛出一异常。
语法: thorw new 异常类("异常提示信息"); 这就是抛出一个异常让别人去处理
代码语言:javascript复制public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int n1 = input.nextInt();
System.out.println("请输入第二个数:");
int n2 = input.nextInt();
//这里没有系统要处理异常的提示,人家不知道处理。有可能在不知情的情况下就出错了,程序就会中断执行
int result = calc(n1,n2);
System.out.println(result);
System.out.println("程序结束");
}
public static int calc(int num1,int num2){
if(num2==0){
throw new RuntimeException("除整不能为0");//抛出一个RuntimeException运行时异常这种系统不会进行检测
}
int result= num1/num2;
return result;
}
}
自已创建一个异常来自定义这种检测性的异常
代码语言:javascript复制ReflectiveOperationException这一个类是检测性的异常类
代码语言:javascript复制/*
继承这个检测性的异常类后就拥有了检测的性能 继承于Exception ,Exception又继承于Throwable类
在Throwable这个类中有getMessage和printStackTrace两个,功能方法,所以我自定义的这个类也继承下来了这两个方法 ,并且异常类可以
设置自己想给出的提示信息,在每个父类 都有接收message这个参数的构造 ,这个是将自定义异常信息一层一层的往上传,最后传到了Throwable类中,设置异常提示信息。所以,我们想自定义异常类设置提示信息,一样要住上传。
*/
//运算除数不能为0异常类
public class ZroeArithmeticException extends Exception {
public ZroeArithmeticException(String message) {
super(message);
}
}
代码语言:javascript复制package com.qf.throwdemo;
import com.qf.throwClass.ZroeArithmeticException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int n1 = input.nextInt();
System.out.println("请输入第二个数:");
int n2 = input.nextInt();
int result = 0;
try {
//系统检测到异常,不处理不行,必须要使用tr...catch处理,或者也往外抛,交给了main方法 ,交jvm处理,jvm遇到异常就会中断程序的执行
result = calc(n1,n2);
} catch (ZroeArithmeticException e) {
e.printStackTrace();
}
System.out.println(result);
System.out.println("程序结束");
}
public static int calc(int num1,int num2) throws ZroeArithmeticException {
if(num2==0){
//这是自定义的检测型异常必须要处理,如果这在抛出异常这里使用了try..catch处理后,以调用者没有警示意义,所以这里不处理,异常向外继承抛,交由调用者来处理
throw new ZroeArithmeticException("除整不能为0");
}
int result= num1/num2;
return result;
}
}