Java中的异常通俗地说就是当程序出现问题的时候,程序是如何处理的,也就是说程序          是如何安全的从问题中解脱的。比如,当你和朋友遇到危险的时候,你可以选择让朋友先给你挡着,获得暂时的脱身,要么你也可以选择和朋友积极地处理这个棘手的问题。这两种情况就是我们后面要说的编译时异常与运行时异常。下面,就让我们一起去看看java中“棘手”的问题都有那些吧:

140940406.png

一:Java中的异常分类

   Throwable是Java中所有异常或错误的超类,其下有两个子类,其中:

   a:Error处理的是Java运行环境中的内部错误或硬件问题,比如内存资源不足,系统崩溃等。这种情况下的问题,大到你处理不了,所以这时的异常会交给JVM处理;

   b:Exception就是我们所指的程序遇到的问题,分为运行时异常和编译时异常。

(1)编译时异常:形如

public class MyException {
    public static void main(String[] args) {
        String a = 2;//程序中给出红×,表示编译通不过
        System.out.println(a);
    }
}

   代码中的第3行编译通不过,表示出现了编译时异常。

   (2)运行时异常:形如

public class MyException {
    public static void main(String[] args) {
        int a = 2;
        int b = 0;
        int c=a/b;
        //if(b>0){
             System.out.println(c);//java.lang.ArithmeticException       
        //}
    }
}

结果:


Exception in thread "main" java.lang.ArithmeticException: / by zero
    at _727.MyException.main(MyException.java:7)

因为代码中的第5行除数为0,在编辑器中编写代码的时候,没有问题,一旦运行,出现了如图所示的结果。

二:异常的处理中的五大关键字

   遇到了问题,我们不能选择逃避,当然也不能硬碰硬,我们可以积极地处理问题,Java中对待异常就是采取了这种try-catch-finally处理策略,也会通过throws向上级抛出异常,或者通过throw抛出自定义异常或者其他。

   1.try:这里面放的是程序中可能出现异常的语句或语句块

   2.catch:这里面放的是try中出现异常时的处理策略

   3.finally:这里面的语句一定会执行,用来返回系统的某种状态

   4.throws:用来向上级抛出异常

   5.throw:用来抛出自定义异常或其他已知的异常

   三:异常的处理及try-catch-finally和throws的联合使用

   1:对于编译时异常

   一般都是try-catch-finally块处理掉。

   (1)方法中可以不处理,最终抛到main方法,一般main方法中禁止在向上抛异常,这就意味着此时main必须处理这个异常

public class MyException {
    public static void main(String[] args) {
        //main中不允许上抛,所以必须用try-catch-finally积极的处理
        try {
            test();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void test()throws Exception{
        //在方法中没有用try-catch-finally处理,直接上抛到main中
        int a=0;
        int b=2;
        int c = b/a;
        System.out.println(c);
    }
}

(2)方法中直接给出处理的策略,不用上抛,则在main中没有问题

public class MyException {
    public static void main(String[] args) {
        // main中不必用try-catch-finally再处理 了
        test();
    }
    public static void test() {
        // 在方法中用try-catch-finally积极处理,就不用上抛了
        int a = 0;
        int b = 2;
        try {
            int c = b / a;
            System.out.println(c);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2:对于运行时异常

       可以用try-catch-finally处理,但是对效率和代码的阅读都有影响,所以一般用if条件来使程序健壮起来。

public class MyException {
    public static void main(String[] args) {
        int a = 2;
        int b = 0;
        if (b != 0) {
            a = a / b;
        } else if (b == 0) {
            throw new ArithmeticException("除数为0   ");
            // 这里用到了throw关键字,抛出了算数运算异常,稍后马上就给您解释
        }
    }
}

三:自定义异常与throw关键字

   1:自定义异常

   虽然说在Java中的Exception几乎可以直接处理许多异常,但是有时候为了更加精准的捕获和处理异常以呈现更好的用户体验,需要我们自定义异常。

   2:如何定义自定义异常?

   (1)自定义异常类名 extends Exception或其子类

   (2)在自定义异常类中提供String做参数的自定义异常类的构造方法,方法体中提供父类用String做参数的构造方法

   即:

public class 自定义异常类类名 extends Exception或他的子类 {
    public 自定义异常类类名(String str) {//提供String做参数的构造方法
        super(str);//调用父类String做参数的构造方法完成创建对象
    }
}

3:自定义异常的使用

       自定义异常类只能通过throw关键字抛出自定义异常类对象,即在某些语句会出现此种自定义异常时,加上下面这个语句

throw new 自定义异常类类名("String字符串");//抛出自定义异常类对象

4:具体事例

      创建Person类,当创建对象时,如果年龄小于0或大于120给出异常提示信息。

       (1)创建自定义异常类

public class AgeException extends Exception{
    //创建自定义异常类
    public AgeException(String str) {
        //提供父类带参数的构造方法
        super(str);
    }
                                                                                                                                                                                                              
}

(2)创建实体类,并在setAge(int age)方法中添加throw语句,抛出自定义异常对象,以检测异常

public class Person {
    private String name;
    private int age; 
    //为了说明问题,此处省略了无参构造,有参构造,name属性的get/set方法以及age属性的get方法,
    public void setAge(int age) throws AgeException {
        if(age<0 || age>120){
            throw new AgeException("年龄不能小于零或者大于120岁"
                    //抛出自定义异常类对象
        }
        this.age = age;
    }
    //为了说明问题,此处省略了重写的toString,equals,hashcode方法
}

   (3)异常测试类1

public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.setName("张三");
        System.out.println("姓名:" + p.getName());
        try {
            p.setAge(220);//注意看此时的结果,应该给出异常哦
        } catch (AgeException e) {
            e.printStackTrace();
        }
        System.out.println();
        System.out.println("年龄:" + p.getAge());
    }
}

   (4)异常测试结果1

姓名:张三
AgeException.AgeException: 年龄不能小于零或者大于120岁
    at AgeException.Person.setAge(Person.java:29)
    at AgeException.Test.main(Test.java:11)
年龄:0

   (5)正常测试2

public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.setName("张三");
        System.out.println("姓名:" + p.getName());
        try {
            p.setAge(22);//注意看此时的结果,应该正确哦
        } catch (AgeException e) {
            e.printStackTrace();
        }
        System.out.println();
        System.out.println("年龄:" + p.getAge());
    }
}

    (6)正常结果2

姓名:张三
年龄:22


        PS一下:有人说try和catch是幸福的一对,无论try怎么对catch发脾气,catch总是会默默地接受,及时catch不在的时候,catch也会把他身后的finally给try


       好幸福呢。。。j_0056.gif