zoukankan      html  css  js  c++  java
  • 异常

    Java代码在运行时期发生的问题就是异常

    异常的继承体系是:

        Throwable: 它是所有错误与异常的超类(祖宗类)
            |- Error 错误
            |- Exception 编译期异常,进行编译JAVA程序时出现的问题
                |- RuntimeException 运行期异常, JAVA程序运行过程中出现的问题

    异常和错误的区别:

    异常一般为XxxException,错误一般为XxxError。

    异常是我们程序自己引起的,我们可以捕获进行处理。

    而错误是jvm自己报出来的,我们无法处理。

    异常

    指程序在编译、运行期间发生了某种异常(XxxException),我们可以对异常进行具体的处理。

    若不处理异常,程序将会结束运行。

    l  异常的产生演示如下:

    public static void main(String[] args) {
    	int[] arr = new int[3];
    	System.out.println(arr[0]);
    	System.out.println(arr[3]);
    // 该句运行时发生了数组索引越界异常ArrayIndexOutOfBoundsException,由于没有处理异常,导致程序无法继续执行,程序结束。
    	System.out.println("over"); // 由于上面代码发生了异常,此句代码不会执行
    }
    

    错误

    指程序在运行期间发生了某种错误(XxxError),Error错误通常没有具体的处理方式,程序将会结束运行。

    Error错误的发生往往都是系统级别的问题,都是jvm所在系统发生的,并反馈给jvm的。我们无法针对处理,只能修正代码。

    l  错误的产生演示如下:

    public static void main(String[] args) {
    int[] arr = new int[1024*1024*100];
    //该句运行时发生了内存溢出错误OutOfMemoryError,开辟了过大的数组空间,导致JVM在分配数组空间时超出了JVM内存空间,直接发生错误。
    }

    抛出异常throw:

    throw new 异常类名(参数);

    throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

    使用格式:

    throw new 异常类名(参数);

    抛出异常throw的使用:

    class ArrayTools{
        //通过给定的数组,返回给定的索引对应的元素值。
        public static int getElement(int[] arr,int index)    {
            /*
            若程序出了异常,JVM它会打包异常对象并抛出。但是它所提供的信息不够给力。想要更清晰,需要自己抛出异常信息。
    下面判断条件如果满足,当执行完throw抛出异常对象后,方法已经无法继续运算。这时就会结束当前方法的执行,并将异常告知给调用者。这时就需要通过异常来解决。
            */
            if(arr==null){
                throw new NullPointerException("arr指向的数组不存在");
            }
            if(index<0 || index>=arr.length){
                throw new ArrayIndexOutOfBoundsException("错误的角标,"+index+"索引在数组中不存在");
            }
            int element = arr[index];
            return element;
        }
    }
        测试类
    class ExceptionDemo3 {
        public static void main(String[] args) {
            int[] arr = {34,12,67}; //创建数组
            int num = ArrayTools.getElement(null,2);// 调用方法,获取数组中指定索引处元素
    //int num = ArrayTools.getElement(arr,5);// 调用方法,获取数组中指定索引处元素
            System.out.println("num="+num);//打印获取到的元素值
        }
    }

    声明异常throw:

    声明异常格式:

    修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2… {   }

    声明异常的代码演示:

    class Demo{
        /*
        如果定义功能时有问题发生需要报告给调用者。可以通过在方法上使用throws关键字进行声明。
        */
        public void show(int x)throws Exception    {
            if(x>0){
                throw new Exception();
            } else {
                System.out.println("show run");
             }
        }
    }

    抛出异常和声明异常的区别:

    抛出异常是自己处理异常,方法内部出现异常后,直接自己处理,并停止程序。

    声明异常是我们声明一个异常,调用者必须去出路该异常,异常处理后还会向下执行。

    捕获异常try…catch…finally

    捕获异常格式:

    try {
        //需要被检测的语句。
    }
    catch(异常类 变量) { //参数。
        //异常的处理语句。
    }
    finally {
        //一定会被执行的语句。
    }

    try:该代码块中编写可能产生异常的代码。

    catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。

    finally有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。

    而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。

    演示如下:

    class ExceptionDemo{
        public static void main(String[] args){ //throws ArrayIndexOutOfBoundsException
            try    {
                  int[] arr = new int[3];
                System.out.println( arr[5] );// 会抛出ArrayIndexOutOfBoundsException
                当产生异常时,必须有处理方式。要么捕获,要么声明。
            }
            catch (ArrayIndexOutOfBoundsException e) { //括号中需要定义什么呢?try中抛出的是什么异常,在括号中就定义什么异常类型。 
                System.out.println("异常发生了");
            } finally {
                  arr = null; //把数组指向null,通过垃圾回收器,进行内存垃圾的清除
    }
            System.out.println("程序运行结果");
        }
    }

    一个try 多个catch组合 :

    l  对代码进行异常检测,并对检测的异常传递给catch处理。对每种异常信息进行不同的捕获处理。

    void show(){ //不用throws 
        try{
            throw new Exception();//产生异常,直接捕获处理
        }catch(XxxException e){
    //处理方式    
        }catch(YyyException e){
    //处理方式    
        }catch(ZzzException e){
    //处理方式    
        }
    }

    注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,

    那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。

    自定义异常类的定义

    每个异常中都调用了父类的构造方法,把异常描述信息传递给了父类,让父类帮我们进行异常信息的封装。

    例如NullPointerException异常类源代码:

    public class NullPointerException extends RuntimeException {
        public NullPointerException() {
            super();//调用父类构造方法
        }
        public NullPointerException(String s) {
            super(s);//调用父类具有异常信息的构造方法
        }
    }

    现在,我们来定义个自己的异常,即自定义异常。

    格式:

    Class 异常名 extends Exception{ //或继承RuntimeException
        public 异常名(){
    }
        public 异常名(String s){ 
    super(s); 
    }
    }

    l  自定义异常继承Exception演示

    class MyException extends Exception{
        /*
        为什么要定义构造函数,因为看到Java中的异常描述类中有提供对异常对象的初始化方法。
        */
        public MyException(){
            super();
        }
        public MyException(String message)    {
            super(message);// 如果自定义异常需要异常信息,可以通过调用父类的带有字符串参数的构造函数即可。
        }
    }

    自定义异常继承RuntimeException演示

    class MyException extends RuntimeException{
        /*
        为什么要定义构造函数,因为看到Java中的异常描述类中有提供对异常对象的初始化方法。
        */
        MyException(){
            super();
        }
        MyException(String message)    {
            super(message);// 如果自定义异常需要异常信息,可以通过调用父类的带有字符串参数的构造函数即可。
        }
    }

    练习:

    l  自定义异常类

    class NoAgeException extends Exception{
        NoAgeException() {
            super();
        }
    
        NoAgeException(String message)    {
            super(message);
        }
    }

    l  Person类

    class Person{
        private String name;
        private int age;
        Person(String name,int age) throws NoAgeException    {
            //加入逻辑判断。
            if(age<0 || age>200)        {
                throw new NoAgeException(age+",年龄数值非法");
            }
            this.name = name;
            this.age = age;
        }
        //定义Person对象对应的字符串表现形式。覆盖Object中的toString方法。
        public String toString()    {
            return "Person[name="+name+",age="+age+"]";
        }
    }

    l  测试类

    class ExceptionDemo{
        public static void main(String[] args) {
            try {
                Person p = new Person("xiaoming",20);
                System.out.println(p);
            }
            catch (NoAgeException ex){
                System.out.println("年龄异常啦");
            }
            System.out.println("over");
        }
    }

    总结:

    构造函数到底抛出这个NoAgeException是继承Exception呢?还是继承RuntimeException呢?

    l  继承Exception,必须要throws声明,一声明就告知调用者进行捕获,一旦问题处理了调用者的程序会继续执行。

    l  继承RuntimeExcpetion,不需要throws声明的,这时调用是不需要编写捕获代码的,因为调用根本就不知道有问题。

    一旦发生NoAgeException,调用者程序会停掉,并有jvm将信息显示到屏幕,让调用者看到问题,修正代码。

     

  • 相关阅读:
    无线鼠标换电池了
    Jython Interactive Servlet Console YOU WILL NEVER KNOW IT EXECLLENT!!! GOOD
    Accessing Jython from Java Without Using jythonc
    jython podcast cool isnt't it?
    Python里pycurl使用记录
    Creating an Interactive JRuby Console for the Eclipse Environment
    微软为AJAX和jQuery类库提供CDN服务
    Download A File Using Cygwin and cURL
    What is JMRI?这个是做什么用的,我真没看懂但看着又很强大
    用curl 发送指定的大cookie的http/https request
  • 原文地址:https://www.cnblogs.com/lixiangyang521/p/7890800.html
Copyright © 2011-2022 走看看