文章目录
一、JAVA 异常
1、Java异常概括
异常:程序运行过程中产生的不正常的情况统称为异常!(程序运行时产生错误)
2、Java中的异常体系
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常, 这两种异常有很大的区别,也称之为非受检查异常(Unchecked Exception)和受检查异常(Checked Exception)。
-
两个子类区别:
-
Error: 程序不应该捕捉的错误,应该交由JVM来处理。一般可能指非常重大的错误。这个错误我们一般获取不到,也无法处理!
-
Exception: 程序中应该要捕获的错误。这个异常类及它的子类是我们需要学习获取要处理的。
-
3、程序中异常的区分
(1)非运行时异常: 也叫可查异常,正确的程序在运行中,很容易出现的、情理可容的异常状况。除了Exception中的RuntimeException及RuntimeException的子类以外,其他的Exception类及其子类(例如:IOException和ClassNotFoundException)都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
(2)运行时异常: RuntimeException 类及其子类被称为运行时异常,也叫未检查异常,是Exception的子类。不需要捕捉的异常超类,但是实际发生异常时,会导致程序停止运行的状况,只是编译时没有报错而已。比如除数为零,数组空指针等等,这些都是在运行之后才会报错。此类异常,可以处理也可以不处理,并且可以避免。而且这个问题的出现肯定是我们的代码不够严谨,需要修正代码。
4、JAVA 中几种常见的异常:
- RuntimeException子类:
异常名称 | 异常描述 |
---|---|
java.lang.ArrayIndexOutOfBoundsException | 数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。 |
java.lang.ArithmeticException | 算术条件异常。譬如:整数除零等。 |
java.lang.SecurityException | 安全性异常 |
java.lang.IllegalArgumentException | 非法参数异常 |
java.lang.ArrayStoreException | 数组中包含不兼容的值抛出的异常 |
java.lang.NegativeArraySizeException | 数组长度为负异常 |
java.lang.NullPointerException | 空指针异常。当应用试图在要求使用对象的地方使用了 null 时,抛出该异常。譬如:调用 null 对象的实例方法、访问 null 对象的属性、计算 null 对象的长度、使用 throw 语句抛出 null 等等。 |
- IOException
异常名称 | 异常描述 |
---|---|
IOException | 操作输入流和输出流时可能出现的异常 |
EOFException | 文件已结束异常 |
FileNotFoundException | 文件未找到异常 |
- 其他异常
异常名称 | 异常描述 |
---|---|
ClassCastException | 类型转换异常类 |
ArrayStoreException | 数组中包含不兼容的值抛出的异常 |
SQLException | 操作数据库异常类 |
NoSuchFieldException | 字段未找到异常 |
NoSuchMethodException | 方法未找到抛出的异常 |
NumberFormatException | 字符串转换为数字抛出的异常 |
StringIndexOutOfBoundsException | 字符串索引超出范围抛出的异常 |
IllegalAccessException | 不允许访问某类异常 |
InstantiationException | 当应用程序试图使用 Class 类中的 newInstance() 方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常 |
java.lang.ClassNotFoundException | 找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历 CLASSPAH 之后找不到对应名称的 class 文件时,抛出该异常。 |
5、异常的处理办法
1、捕获异常
- 我们在日常开发中会遇到各种不同的错误,我们需要根据产生错误的原因去区分和处理这些错误。
- 那么我们自己如何处理异常呢?
- 通过 Try…Catch… finally将异常捕获并尽可能的解决
- Try…Catch… finally 的作用
- Try 的作用:捕捉代码块中的异常
- Catch 的作用:Try 捕捉的异常会抛给 Catch ,可以在此模块中进行异常分类和异常的相关处理
- finally 的作用:用于释放资源,减小程序负荷
- Try…Catch… finally 的作用
- 通过 Try…Catch… finally将异常捕获并尽可能的解决
- 那么我们自己如何处理异常呢?
-
Try…Catch的格式
try { 可能出现问题的代码; }catch(异常名 变量) { 针对问题的处理; }finally { 释放资源; }
try 后的catch代码块 只能匹配成功一个
catch后声明的异常为父类时,它能够捕捉的异常为它本身+所有子类异常(多态的体现)
注意:catch代码块捕获异常时,子类异常必须定义在父类异常前面,否则会编译出错
Demo代码示例:
//注:如何程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。然后把异常的名称,原因及出现的问题等信息输出在控制台。
//所以说,看控制台很重要!!!!!!!!!
public class DemoException {
public static void main(String[] args) {
int x = 9;
int y = 0;
//单个异常的处理
/*System.out.println(x/y);*/
//这里运行之后会报出以下错误
/* Exception in thread "main" java.lang.ArithmeticException: / by zero
at JavaSE_Demo_02.Demo_10.Deme_Throwable.Demo_Exception.DemoException.main(DemoException.java:16)*/
/* 对错误进行讲解:
*因为Java的程序都是放在JVM上进行执行的,当程序运行时jvm发现运算是已经违反了数学运算规则,
* java将这种常见的问题进行描述,并封装成了对象叫做ArithmeticException
当除0运算发生后,jvm将该问题打包成了一个异常对象。
并将对象抛给调用者main函数,new ArithmeticException(“/by zero”);
main函数收到这个问题时,有两种处理方式:
1. 自己将该问题处理,然后继续运行
2.自己没有针对的处理方式,只有交给调用main的jvm来处理
jvm有一个默认的异常处理机制,就将该异常进行处理,并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上
同时将程序停止运行
* */
///
//当发现这些错误的时候,Java为我们提供了处理异常的方式,Try…Catch,将异常捕获。并且还可以在 catch 体中做自己的逻辑处理,catch中主要是做代码异常的处理
/* 如果一段代码存在多个错误,这时候如果每个问题都去try的话会显得很琐碎,可以使用多个catch来解决
(和 if (){}|else的格式很类似,同理catch也是只执行一个,执行完就跳出Try…Catch)*/
//注:如果写的是多个catch体,那么异常类型会选择最大的异常来打印,如果异常等级是一样的,那么就按顺序来
// 所以在捕获异常时,需要按照从小到大的顺序来捕获
try {
System.out.println(x/y);
}catch (Error error){
if(x !=0 && y !=0){
System.out.println(x/y);
}else {
System.out.println("除数不能为0");
}
System.out.println("Error");
}catch (Exception exception){
if(x !=0 && y !=0){
System.out.println(x/y);
}else {
System.out.println("除数不能为0");
}
System.out.println("Exception");
}catch (Throwable throwable){
if(x !=0 && y !=0){
System.out.println(x/y);
}else {
System.out.println("除数不能为0");
}
System.out.println("Throwable");
}finally {
System.out.println("释放资源");
}
}
}
运行结果:
通过运行结果可以发现,一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try…catch继续执行后面的语句。
2、抛出异常
1、throws
有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。
为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
- 格式:
- throws 异常类名
- 注意:这个格式必须跟在方法的括号后面。
Demo代码示例:
public class DemoExceptionThrows {
public static void main(String[] args) {
try {
method();
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("但是我要在家学习");
method2();
}
// 编译期异常的抛出,编译不通过,我们就要抛出异常了
public static void method() throws ParseException {
String s = "2016-09-03";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(s);
System.out.println(d);
}
// 运行期异常的抛出
public static void method2() throws ArithmeticException {
int a = 10;
int b = 0;
System.out.println(a / b);
}
}
2、throw
- 手动产生异常:throw
- 格式:throw new 异常类名();
-
throws和throw的区别
-
throws
- 用在方法声明后面,跟的是异常类名
- 可以跟多个异常类名,用逗号隔开
- 表示抛出异常,由该方法的调用者来处理
- throws表示出现异常的一种可能性,并不一定会发生这些异常
-
throw
- 用在方法体内,跟的是异常对象名
- 只能抛出一个异常对象名
- 表示抛出异常,由方法体内的语句处理
- throw则是抛出了异常,执行throw则一定抛出了某种异常
-
手动抛出异常的代码示例:
public class DemoThrow {
public static void main(String[] args) throws Exception {
m1();
}
public static void m1() throws Exception {
System.out.println("m1----------start");
m2();
// 手动抛出受查异常
throw new Exception();
//System.out.println("m1----------end");
}
public static void m2() {
System.out.println("m2----------start");
// 手动抛出运行时异常,需要携带信息“程序因为异常而终止”
throw new RuntimeException("程序因为异常而终止");
//System.out.println("m2----------end");
}
}
运行结果:
6、自定义异常
java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类是一个异常类,就必须继承自Exception或者RuntimeException。
自定义异常类的使用步骤如下:
1、自定义异常类继承 Exception 类
/**
* 自定义异常类
*/
public class MyException extends Exception {
//异常信息
private String message;
//构造函数
public MyException(String message){
super(message);
this.message = message;
}
//获取异常信息,由于构造函数调用了super(message),不用重写此方法
//public String getMessage(){
// return message;
//}
}
2、在要抛出异常的函数使用throws关键字
/**
* 在需要抛出异常的地方使用异常类
*/
public class UseMyException {
private String name;
private String password;
public UseMyException(String name,String password){
this.name = name;
this.password = password;
}
public void throwException(String password) throws MyException{
if (!this.password.equals(password)){
throw new MyException("密码不正确!");
}
}
}
3、测试,使用try-catch处理异常
/**
* 测试异常
*/
public class TestException {
public static void main(String[] args) {
UseMyException ex = new UseMyException("admin","123");
try{
ex.throwException("1234");
}catch (MyException me){
System.out.println("MyException:"+me.getMessage());
}
}
}
运行结果:
7、JAVA 中异常使用的注意事项
扩展: java中处理异常的9个注意事项