zoukankan      html  css  js  c++  java
  • JAVA异常

    JAVA异常

    介绍

    异常是在程序中出现的不符合预期的各种情况。它是程序设计的一部分,异常并不是错误,它不一定是坏的情况。JAVA有错误和异常两种不同的类型,其中错误(ERROR)指的是程序无法处理的错误,异常(Exception)指的是程序本身可以处理的异常。

    • ERROR:程序无法处理,这表明程序中出现严重的问题。大多与JVM有关,例如JVM内存不够的时候,将出现OutOfMemoryError。

    • EXCEPTION:程序可以处理,分为运行时异常(Runtime Exception)和非运行时异常。

      • 运行时异常也是Unchecked Exception, 这些不会在编译期进行检查,会在程序运行期间出现问题的时候出现。这些异常一般都是程序执行造成的错误,需要尽量避免这种错误。
      • 非运行时异常是checked Exception,也就是程序会在编译期进行检查,例如IOException。

    异常的处理方式

    异常的处理机制有捕获异常和抛出异常。

    捕获异常的一般结构:

    try
        {
             // 可能发生异常的代码
            // 如果发生了异常,那么异常之后的代码都不会被执行
        }
        catch (Exception e)
        {
            // 异常处理代码
        }
        finally
        {
            // 不管有没有发生异常,finally语句块都会被执行
        }
    

    用除法举例说明:

    public class ExceptionTest
    {
        public static void main(String[] args)
        {
            int c = 0;
            try
            {
                int a = 3;
                int b = 0;
    
                // 这块代码出现了异常
                c = a / b;
    
                // 那么异常之后的代码都不会被执行
                System.out.println("Hello World");
            }
            catch (ArithmeticException e)
            {
                e.printStackTrace();
            }
            finally
            {
                //不管有没有发生异常,finally语句块都会被执行
                System.out.println("Welcome");
            }
    
            System.out.println(c);
            // 当b为0时,有异常,输出为c的初始值0
        }
    }
    

    当然一个try后面可以跟多个catch,但是不管多少个,最多只会有一个catch块被执行。

    非运行时异常的处理方式

    处理方式有两种:

      1.使用try..catch..finally进行捕获;

      2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。

    处理方式1:将异常捕获

    将异常捕获
    
    public class ExceptionTest2
    {
        public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
        {
            System.out.println("Hello World");
    
            // 抛出异常
            throw new Exception();
        }
    
        public static void main(String[] args)
        {
            ExceptionTest2 test = new ExceptionTest2();
    
            try
            {
                test.method();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                System.out.println("Welcome");
            }
    
    
        }
    
    }
    

    处理方式2:将异常继续向外抛出

    将异常抛出
    
    public class ExceptionTest2
    {
        public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
        {
            System.out.println("Hello World");
    
            // 抛出异常
            throw new Exception();
        }
    
        public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
        {
            ExceptionTest2 test = new ExceptionTest2();
    
            test.method(); // main方法需要对异常进行处理
    
            // 执行结果:
            // Hello World
            // Exception in thread "main" java.lang.Exception
            // at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
            // at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
        }
    
    }
    

    运行时异常的处理方式

    对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。

    自定义异常

    所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。

      通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。

      自定义异常可以用于处理用户登录错误,用户输入错误提示等。

      自定义异常的例子:

      自定义一个异常类型:
      

    public class MyException extends Exception
    {
        public MyException()
        {
            super();
        }    
        public MyException(String message)
        {
            super(message);
        }
    }
    

    处理方式

    处理方式也分为throws 和 try...catch

    一种异常处理方式
    
    public class ExceptionTest4
    {
    
        public void method(String str) throws MyException
        {
            if(null == str)
            {
                throw new MyException("传入的字符串参数不能为null!");
            }
            else
            {
                System.out.println(str);
            }
        }
        
        public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
        {
            ExceptionTest4 test = new ExceptionTest4();
            test.method(null);
        }
    }
    

    Throws抛出异常的规则:

    1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
    
    2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误
    
    3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
    
    
    4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。
    
    异常处理方式二
    
    public class ExceptionTest4
    {
    
        public void method(String str) throws MyException
        {
            if (null == str)
            {
                throw new MyException("传入的字符串参数不能为null!");
            }
            else
            {
                System.out.println(str);
            }
        }
    
        public static void main(String[] args)
        {
            //异常处理方式2,采用try...catch语句
            try
            {
                ExceptionTest4 test = new ExceptionTest4();
                test.method(null);
    
            }
            catch (MyException e)
            {
                e.printStackTrace();
            }    
            finally
            {
                System.out.println("程序处理完毕");
            }
    
        }
    }
    

    前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块。

    try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。

    catch 块:用于处理try捕获到的异常。

    finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
    在以下4种特殊情况下,finally块不会被执行:

    1)在finally语句块中发生了异常。
    2)在前面的代码中用了System.exit()退出程序。
    3)程序所在的线程死亡。
    4)关闭CPU。
    

    自定义异常

      下面这个例子,定义了两种自定义的异常类型:

    多种异常 
    
    public class MyException extends Exception
    {
    
        public MyException()
        {
            super();
        }
        
        public MyException(String message)
        {
            super(message);
        }
    }
    
    
    public class MyException2 extends Exception
    {
        public MyException2()
        {
            super();
        }
        public MyException2(String message)
        {
            super(message);
        }
    
    }
    
    
    public class ExceptionTest4
    {
    
        public void method(String str) throws MyException, MyException2
        {
            if (null == str)
            {
                throw new MyException("传入的字符串参数不能为null!");
            }
            else if ("hello".equals(str))
            {
                throw new MyException2("传入的字符串不能为hello");
            }
            else
            {
                System.out.println(str);
            }
        }
    
        public static void main(String[] args)
        {
            // 异常处理方式2,采用try...catch语句
            try
            {
                ExceptionTest4 test = new ExceptionTest4();
                test.method(null);
    
            }
            catch (MyException e)
            {
                System.out.println("进入到MyException catch块");
                e.printStackTrace();
            }
            catch (MyException2 e)
            {
                System.out.println("进入到MyException2 catch块");
                e.printStackTrace();
            }
            finally
            {
                System.out.println("程序处理完毕");
            }
    
        }
    }
    

    我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。
    如果异常类型是独立的,那么它们的前后顺序没有要求。

    JAVA常见异常

    在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:

    • runtimeException子类:

      1. java.lang.ArrayIndexOutOfBoundsException
        数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
      2. java.lang.ArithmeticException
        算术条件异常。譬如:整数除零等。
      3. java.lang.NullPointerException
        空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
      4. java.lang.ClassNotFoundException
        找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
      5. java.lang.NegativeArraySizeException 数组长度为负异常
      6. java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
      7. java.lang.SecurityException 安全性异常
      8. java.lang.IllegalArgumentException 非法参数异常
    • IOException

      1. IOException:操作输入流和输出流时可能出现的异常。
      2. EOFException 文件已结束异常
      3. FileNotFoundException 文件未找到异常
    • 其他

      1. ClassCastException 类型转换异常类
      2. ArrayStoreException 数组中包含不兼容的值抛出的异常
      3. SQLException 操作数据库异常类
      4. NoSuchFieldException 字段未找到异常
      5. NoSuchMethodException 方法未找到抛出的异常
      6. NumberFormatException 字符串转换为数字抛出的异常
      7. StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
      8. IllegalAccessException 不允许访问某类异常
      9. InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

    转载自:

    1. http://www.cnblogs.com/mengdd/archive/2013/02/03/2890923.html
    2. http://blog.csdn.net/hguisu/article/details/6155636
  • 相关阅读:
    牛客练习赛24 E:青蛙(最短路)
    菜根谭#10
    菜根谭#9
    菜根谭#8
    菜根谭#7
    菜根谭#6
    菜根谭#5
    菜根谭#4
    菜根谭#3
    菜根谭#2
  • 原文地址:https://www.cnblogs.com/SpeakSoftlyLove/p/5584973.html
Copyright © 2011-2022 走看看