java异常:Throwable子类Error与Exception的区别,三种异常的处理方法,继承中的异常处理,异常使用的注意事项异常

java异常:Throwable子类Error与Exception的区别,三种异常的处理方法,继承中的异常处理,异常使用的注意事项异常_第1张图片
**Throwable:**在程序定义中一般指不期而至的各种情况,如:文件找不到、网络连接失败、非法参数等。异常是一种事件,它发生在程序运行期间、或者代码编译时候,它干扰了正常的程序指令流程继续下去。Java通过API中的Throwable类的众多子类描述各种不同的异常。其中Error与Exception也都是Throwable的两个重要子类。

Error与Exception的区别

**Error:**即错误,是在程序编译时出现的错误,表示在运行应用程序中较严重的问题,一般与代码无关,只能通过修改程序才能修正。一般是JVM(Java虚拟机)的相关问题。如系统崩溃,虚拟机错误,内存不足,动态链接失败等。
例如两个比较常见的错误,一个是Virtual MachineError(Java虚拟机运行错误) 代码在运行时JVM出现的问题;
还有一个是OutOfMemoryError,即JVM不再继续执行操作所需的内存资源。
对于这种错误程序本身是无法恢复和预防的,当这些错误发生时,JVM会选择线程停止。

**Exception:**即异常,是指程序本身可以处理的异常,可以捕获且可能可以恢复。当遇到这类异常时,要尽可能处理异常,增强代码的健壮性,使程序恢复运行。

Exception的两类划分

Exception可以分为CheckedException(UnCheckedException)编译异常(非运行时异常)和RuntimeException运行时异常

**RuntimeException运行时异常:**就是我们在开发测试功能时程序终止,控制台出现异常
常见的有:
ArithmeticException 算数异常

NullPointerException 空指针异常(最容易出现最容易犯的错)

ArrayIndexOutOfBoundsException 索引超出异常

IndexOutOfBoundsException 下标越界异常

ClassCastException 两个类型转换不兼容

NumberFormatException 数字格式异常
对于运行时异常,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。

故该类的异常处理方法有:(下面会对两种方法进行讲解)

  1. 抛出异常
  2. 捕获异常:使用try-catch对异常进行捕获
  3. 修改代码,使代码更健壮

CheckedException(UnCheckedException)编译异常:也叫检查异常或非运行异常,也就是程序在编译时就出现异常。
常见的异常有:
IOException输入或输出异常(即写读异常)

FileNotFoundException文件未被找到

SQLException数据库交互异常
对于非运行时异常,java编译器强制程序员必须进行捕获处理,如果不进行捕获或者抛出声明处理,编译无法通过。
故该类的异常处理方法有:(下面会对两种方法进行讲解)

  1. 抛出异常
  2. 捕获异常:使用try-catch对异常进行捕获

捕获异常

使用try和catch关键字,对异常先进行捕获,再进行处理。
try中包围的代码表示这段代码可能会发生异常,如果发生异常,便会被catch捕获到,然后在catch块中对异常进行处理。
下面看一个例子:

public static void main(String[] args) {
		try {
			  File file = new File("e:/demo1.txt");
			  if(!file.exists())
			    file.createNewFile();
			} catch (IOException e) {
			  // TODO: handle exception
			}
	}

抛出异常

何为抛出异常?
一个方法不处理这个异常,而是调用层次向上传递,谁调用这个方法,这个异常就由谁来处理。此时需要用到throw或throws关键字。

第一种方法是使用throws关键字 :
如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。
用它修饰的方法向调用者表明该方法可能会抛出异常(可以是一种类型,也可以是多种类型,用逗号隔开)
位置: 写在方法名 或方法名列表之后 ,在方法体之前。
下面看一个具体的例子:

public class Demo01{

	public static void createException() throws IOException{
		File file = new File("e:/Demo1.txt");
        if(!file.exists())
            file.createNewFile();
	}
	public static void main(String[] args) {
		try{
			createException();
		}catch(Exception e){
			// TODO: handle exception
		}
	}
}

在实际的createException方法中并没有捕获异常,而是用throws关键字声明抛出异常,即告知这个方法的调用者此方法可能会抛出IOException。那么在main方法中调用createException方法的时候,再采用try…catch块对异常进行捕获。

PS:如果最终将异常抛给main方法,则相当于交给jvm自动处理,此时jvm会简单地打印异常信息

第二种方法就是使用throw手动来抛出异常对象 :
将产生的异常抛出(强调的是动作),抛出的既可以是异常的引用,也可以是异常对象。(位置: 方法体内
下面看一个具体的例子:

public class Demo02 {
	public static void main(String[] args) {
        try {
            int[] data = new int[]{1,2,3,4};
            System.out.println(getDataByIndex(5,data));
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public static int getDataByIndex(int index,int[] data) {
        if(index<0||index>=data.length)
            throw new ArrayIndexOutOfBoundsException("数组下标越界");
        return data[index];
    }
}

当然还可以自定义异常,自定义异常类继承于Exception类,其他操作相同。

继承中的异常处理

1.若父类的方法中没有抛出异常,则子类在重写该方法时不可以抛出异常
2.若父类的方法声明了一个异常,那么子类在重写该方法时声明的异常不能大于父类(即不能是父类异常的上级异常)
3.若父类的方法声明的异常只有非运行异常或者运行异常其中的一个,那么子类在重写这个方法时也只能有与父类相同类型的一种异常。

关于异常使用的注意事项

1.final finally finalize的区别
final用于修饰类 方法 属性,修饰类表示类无法被继承,修饰方法表示方法无法被重写,修饰属性表示是常量
finalize是Object自带方法,当System.gc()会先调用此方法
finally与try-catch合用,表示无论如何都会执行,在return前执行,一般用于关闭资源

2.不要频繁使用异常,可能会影响程序的性能

3.只能由一个try,但可以对应多个catch块

4.不要使用空catch块,捕获了异常又对它不进行处理,那么相当于隐藏了这个异常,可能会导致程序出现不可预判的结果。

5.在finally中可以放释放资源的语句,例如关闭文件等操作,可以节约程序的资源,避免引起不必要的因为资源未关闭而导致的异常或者是资源的浪费。

你可能感兴趣的:(java,SE基础知识,java)