异常

来源:互联网 发布:app store 软件 发票 编辑:程序博客网 时间:2024/05/18 01:07

异常:

    程序在运行期间,发生了不可预测的事件,它阻止了我们程序的正常运行!
    
异常处理机制:
    在我们的程序发生异常之后,代码能按照我们事先设计的顺序 继续执行,代码的健壮性!


异常的分类


  所有异常和错误的父类====》Throwable
  异常的分类:
   01.运行时异常  RuntimeException
   02.受查异常     CheckedException

Java提供了两类主要的异常:runtime exception和checked exception。checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。 

但是另外一种异常:runtime exception,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。 

以前一直没仔细想过出现运行时异常了系统会怎样工作,最近在一个模块排错时,才无意中发现了系统是如何处理运行时异常。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。






  IOException  

  FileNotFoundException   文件没找到
  
  ArithMeticException   算术异常
  InputMismatchException   输入类型不匹配
  NullPointerException 空指针异常
  ClassNotFoundException 没有找到类
  ClassCastException     类型转换异常 
  NumberFormatException 数字转换格式异常//包装类




异常和异常链的使用


异常的处理分为两种方式:
  01. try  catch   finally
  02.throw抛出异常, throws声明异常


 try
 01.不能单独使用,必须和catch/finally联合使用
 02.存放可能出现异常的代码
 03.如果try代码块中出现了异常,会去匹配catch代码块对应的异常类型,
         没有匹配的类型,直接进入finally
 catch
 01.可以有多个catch块,每个catch都能捕获一个异常
 02.多个catch块捕获的异常类型不允许重复
 03.多个catch块的异常类型 必须是 级别从小到大排列
 04.如果多个catch块都能匹配,默认使用第一个匹配的
 05.如果try中都没有发生异常,catch代码块被忽略
 06.每个代码块中的变量 都是 私有的
 
 finally
 01.无论代码是否发生异常,都会执行的代码块
 02.如果遇到了System.exit(0)(正常退出)或者System.exit(非0异常)才不会执行finally
 03.如果try代码块中出现了 return ,如果在return前面代码出现了异常,则不是return跳出
  main方法了 (不出现异常时)也是要先执行finally 之后,再回到return再跳出main方法
 04.后续关闭流,释放数据库连接资源(文件和网络finally用途)
 
 
 
 throw抛出异常
 
  01.语法   throw  new  异常类型(异常信息)
  02.异常类型必须是Exception或者其子类
  03.一个throw只能 抛出一个异常
  04.只能出现在方法体内
  05.针对于抛出的异常  我们能使用两种方式解决
      001.try  catch   finally
      002.使用throws声明异常
  06.抛出异常的类型必须是 声明异常类型本身或者其子类
  
  
 throws声明异常
  01.语法  throws  异常类型1,异常类型2...
  02.定义在方法的参数列表之后,可以声明多个异常
  03.throws所在的方法不处理异常,方法的调用者去处理异常
  04.如果在main方法中使用throws,则是JVM来处理异常




异常链的使用
   把我们捕获的异常包装成一个新的异常,继续抛出!新异常中记录了异常的原始信息!
  便于我们找到异常的根本原因!
 
   import java.io.IOException;
import java.sql.SQLException;
import java.util.InputMismatchException;


public class LinkDemo {


// main方法
public static void main(String[] args) {
try {
firstException();
} catch (SQLException e) {
e.printStackTrace();
}
}


// 第1个异常
private static void firstException() throws SQLException {
try {
secondException();
} catch (IOException e) {
e.printStackTrace();
throw new SQLException("第1个异常", e);
}
}


// 第2个异常
private static void secondException() throws IOException {
try {
thirdException();
} catch (InputMismatchException e) {
e.printStackTrace();
throw new IOException("第2个异常", e);
}
}


// 第3个异常
private static void thirdException() throws InputMismatchException {
throw new InputMismatchException("根本的异常");
}
}




自定义异常
 01.异常类必须是Throwable的子类
 02.自定义异常类 继承 RuntimeException ,Exception


package com.xdf.exception;


/**
 * 
 * 针对于Student的异常类
 */
public class StudentException extends Exception {


public StudentException(String msg) {
super(msg);
}


public StudentException(String msg, Throwable e) {
super(msg, e);
}


}
package com.xdf.exception;


public class NameException extends StudentException {


public NameException() {
super("姓名异常");
}


}
package com.xdf.exception;


public class AgeException extends StudentException {


public AgeException() {
super("年龄异常");
}


}


package com.xdf.exception;


import java.util.Scanner;


public class StudentDemo {


public static void main(String[] args) throws StudentException {


Scanner input = new Scanner(System.in);
System.out.println("请输入异常(age/name)");
String answer = input.next();
if (answer.equals("age")) {
throw new AgeException();
} else if (answer.equals("name")) {
throw new NameException();
} else {
createStudent();
}


}


private static void createStudent() throws StudentException {
throw new StudentException("学生创建异常");
}


}


结果:

请输入异常(age/name)
age
Exception in thread "main" com.xdf.exception.AgeException: 年龄异常
at com.xdf.exception.StudentDemo.main(StudentDemo.java:13)




一、基本概念


Throwable是所有异常的根,java.lang.Throwable
Error是错误,java.lang.Error
Exception是异常,java.lang.Exception


Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。


Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。


         这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。


Exception(异常):是程序本身可以处理的异常。


     Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。


   注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。


二、Exception


一般分为Checked异常和Runtime异常,所有RuntimeException类及其子类的实例被称为Runtime异常,不属于该范畴的异常则被称为CheckedException。


①Checked异常


只有java语言提供了Checked异常,Java认为Checked异常都是可以被处理的异常,所以Java程序必须显示处理Checked异常。如果程序没有处理Checked异常,该程序在编译时就会发生错误无法编译。这体现了Java的设计哲学:没有完善错误处理的代码根本没有机会被执行。对Checked异常处理方法有两种


1 当前方法知道如何处理该异常,则用try...catch块来处理该异常。
2 当前方法不知道如何处理,则在定义该方法是声明抛出该异常。


按 Ctrl+C 复制代码


package cn.xy.test;  
  
import java.io.IOException;  
  
/** 
 * Checked异常测试方法 
 * @author xy 
 * 
 */  
public class CheckedExceptionMethods  
{  
    // 总异常类,既有checkedException又有RuntimeException,所以其中的checkedException必须处理  
    public void method1() throws Exception  
    {  
        System.out.println("我是抛出异常总类的方法");  
    }  
  
    // 捕获并处理这个异常  
    public void testMethod1_01()  
    {  
        try  
        {  
            method1();  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
    }  
  
    // 把异常传递下去  
    public void testMethod1_02() throws Exception  
    {  
        method1();  
    }  
  
    public void testMethod1_03() throws Exception  
    {  
        throw new Exception();  
    }  
  
    public void testMethod1_04()  
    {  
        try  
        {  
            throw new Exception();  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
    }  
  
    // checkedException典型代表IOException  
    public void method2() throws IOException  
    {  
        System.out.println("我是抛出IO异常的方法");  
    }  
  
    public void testMethod2_01()  
    {  
        try  
        {  
            method2();  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
    }  
  
    public void testMethod2_02() throws Exception  
    {  
        method2();  
    }  
  
}
按 Ctrl+C 复制代码
我们比较熟悉的Checked异常有


Java.lang.ClassNotFoundException
Java.lang.NoSuchMetodException
java.io.IOException


 


②RuntimeException


Runtime如除数是0和数组下标越界等,其产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。所以由系统自动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显示捕获它们。


复制代码
 1 package cn.xy.test;  
 2   
 3 /** 
 4  * 运行时异常测试方法 
 5  * @author xy 
 6  * 
 7  */  
 8 public class RuntimeExcetionMethods  
 9 {  
10     public void method3() throws RuntimeException  
11     {  
12         System.out.println("我是抛出运行时异常的方法");  
13     }  
14   
15     public void testMethod3_01()  
16     {  
17         method3();  
18     }  
19   
20     public void testMethod1_02()  
21     {  
22         throw new RuntimeException();  
23     }  
24 }  
复制代码
我们比较熟悉的RumtimeException类的子类有


Java.lang.ArithmeticException
Java.lang.ArrayStoreExcetpion
Java.lang.ClassCastException
Java.lang.IndexOutOfBoundsException
Java.lang.NullPointerException


三、Error


当程序发生不可控的错误时,通常做法是通知用户并中止程序的执行。与异常不同的是Error及其子类的对象不应被抛出。


Error是throwable的子类,代表编译时间和系统错误,用于指示合理的应用程序不应该试图捕获的严重问题。


Error由Java虚拟机生成并抛出,包括动态链接失败,虚拟机错误等。程序对其不做处理。






原创粉丝点击