什么是异常
在生活中,常常会发生我们意想不到的事情,比如你正常坐车上班,突然一天因为汽车抛锚迟到了;做饭时,因为煤气用完了没火了…
我们会因为各种情况遇到一些问题,这些就是异常。
在程序中,我们会遇到文件找不到,参数不合法,格式不正确等等情况,我们将程序遇到的一些意外的情况叫做异常,英文Exception。
异常的分类
异常分为异常和错误,异常又分为编译时异常和运行时异常
Error和Exception有什么区别?
Error就是由于重大问题导致程序无法继续运行。JVM一般会终止线程。
Exception是可以被程序捕获处理的意外情况。
1. 编译时异常
编译时异常是程序在编译时会出的异常,比如要打开一个文件,而这个文件不存在时,就会爆一个异常。
异常包括:
- ClassNotFoundException
- FileNotFoundException
- SQLException
- NoSuchFieldException
- NoSuchMethodException
- …
编译时异常是必须要处理的,不然程序无法编译通过。当我们的程序访问程序以外我们无法绝对控制的内容时就必须处理这些异常。
2. 运行时异常
运行时异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
其下包括:
- ArrayIndexOutOfBoundsException (数组下标越界)
- NullPointerException (空指针异常)
- ArithmeticException (算术异常)
- Missing ResourceException (丢失资源)
- ClassNotFoundException (找不到类)等异常
这些异常是不检查异常,程序里面可以捕获处理。
3. 错误Error
错误不是异常, 而是脱离程序员控制的问题,与程序猿编写执行的操作无关,是由于重大问题导致程序无法继续运行。由JVM虚拟机抛出。
错误在代码中通常被忽略。例如, .当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
- Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM) 一般会选择线程终止;
- 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError) 、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
异常的处理
1、使用try catch处理异常
try{
这里是可能出现异常的代码
}catch(异常类型 异常对象){
处理异常的代码
}
public class IOExceptionTest1 {
public static void main(String[] args) {
File f = new File("abc.txt");
try {
f.createNewFile();
}catch(IOException e) {
System.out.println("出现异常");
}
}
}
说明:
- try语句块中,任何一句代码一旦出现异常,则该代码之后的所有try中的语句不会再运行。
- catch中可以捕获的类型只有当前申明的类型和当前申明类型的子孙类。
- 如果出现类多个不同类型异常,我们可以使用多个catch进行处理,当然也可以写一个catch进行捕获,那么这个catch块的异常类型必须可以捕获多种不同的异常
- 如果多个catch中出现类父子类关系,则一定要将子类异常写在父类异常之前
finally语句块
finally语句块,表示最终要执行的语句块。
try{
}catch(){
}finally{
//finally语句块
}
finally语句块的意思是:无论是否出现异常,finally中的语句必须执行。一定会执行。
final、finally和finalize有什么关系?
final是一个修饰符,表示最终的,修饰的类无法被继承,修饰的方法无法被重写,修饰的量无法被修改。
finally是异常处理中的一个语句块,finally语句无论是否出现异常一定会执行,一般都是用来释放资源。
finalize是Object中定义的一个方法,是GC在回收对象之前调用的一个方法,用来判断对象是否可以回收。
2. 使用throws 抛出异常
我们在一个方法中如果出现异常,但是又不做处理的时候,我们可以通过throws抛出异常。调用这个方法的时候,就必须处理这个异常。
public static test()throws IOException{
test1();
}
//throws后面是可以申明多个异常的
public static test1()throws IOException,FileNotFoundException{
...
}
还可以使用throw手动抛出异常
public static void main(String[] args) {
System.out.println("请输入年龄:");
try {
int age = new Scanner(System.in).nextInt();
if(age<0) {
Exception e = new Exception("年龄不能小于0");
throw e;
}
} catch (Exception e) {
e.printStackTrace();
}
}
throw关键字常见的用法是将编译期异常修改为运行时异常抛出:
}catch(IOException e) {
e. printStackTrace( ) ;
//将编译器异常包裹为一一个运行时异常手动抛出
throw new RuntimeException(e);
}finally {
自定义异常
我们可以自己定义异常,继承exception类即可。
Exception的构造方法:
RuntimeException的构造方法:
- 无参数的就是创建一个没有任何信息的异常对象。
- 一个参数就是创建一个含有异常信息的异常对象。
- 两个参数的就是创建一个含有异常信息,并且使用另外一个Throwable对象创建的一个异常对象。
- 使用Thrwoable对象创建要给新的Exception。
1. 自定义异常创建
//自定义的异常类
public class MyException extends Exception {
//传递数字>10; .
private int detail ;
public MyException(int a) {
this.detail = a;
}
//toString:异常的打印信息
@Override
public String toString() {
return "MyException{" + detail + '}' ;
}
}
声明异常
//可能会存在异常的方法
static void test(int a) throws MyException {
System.out.println("传递的参数为: "+a);
if (a>10){
throw new MyException(a); //抛出
}
System.out.print1n("OK");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
System.out.println( "MyException=>"+e);
}