zoukankan      html  css  js  c++  java
  • 对java异常的总结及java项目中的常用的异常处理情况

    文章涉及内容来源:黑马程序员自学整理的笔记,网上查阅资料,以及转载名为墨钺的博客大佬,附上博客转载地址:https://www.cnblogs.com/gothic-death/p/9946415.html

    在说java异常处理情况之前简单说下:java中异常的定义。

    java程序在运行时出现的不正常情况称之为异常。为了防止此类情况发生后及时处理该异常,java将所有可能发生异常的情况用类的形式进行描述和封装。描述不正常情况的类称为异常类。以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问题代码相分离,提高了阅读性。其实异常就是java通过面对对象的思想将问题封装成对象,用异常类对其描述,不同的问题用不同的异常类进行具体的描述,如空指针和数组越界等。

    问题很多,意味着描述的类也挺多,将其共性进行向上抽取,形成了异常体系,最终问题(不正常情况)就分成了两大类。

    该体系的特点就在于Throwable及其所有子类都具有可抛性,且该子类的后缀名都是以其父类命名的,阅读性极强。

    Throwable:无论是error还是异常都是问题,只要是问题发生,就应该抛出,让调用者知道并处理。

    可抛性到底是什么呢?怎么体现可抛性呢?

    其实是通过两个关键字来体现的,throws和throw,凡是可以被这两个关键字所操作的类和对象都具有可抛性。

    一般不可处理的:在java中被称作error。特点:是由JVM抛出的严重性问题,这种问题发生一般不针对处理,直接修改程序。

    可以处理的:叫做Exception。

    其中Exception又被分为两类:编译时异常和运行时异常。

    编译时异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。这样的问题都可以针对性的处理。

    运行时异常:就是Exception中的RuntimeException和其子类。这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的或者引发了内部状态的改变导致的。这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。

      

    说了这么多,接下来说下自定义异常类所需要注意的事项:

    首先说下throw和throws的区别:

    1.throws使用在函数上,throw使用在函数内。

    2.throws抛出的是异常类,可以抛出多个,中间用逗号进行隔开。throw抛出的是异常对象。

    其次说下继承的问题:

    自定义异常时,要么继承Exception。要么继承RuntimeException。两者只能选其一。

    接下来说下格式要求和注意点:

       

    异常处理的原则:

    1、函数内容如果抛出需要检测的异常,那么函数上必须要声明。

    否则必须在函数内用trycatch捕捉,否则编译失败。


    2、如果调用到了声明异常的函数,要么trycatch要么throws,否则编译失败。

    3、什么时候catch,什么时候throws 呢?
    功能内容可以解决,用catch。
    解决不了,用throws告诉调用者,由调用者解决 。

    4、一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理。
    内部有几个需要检测的异常,就抛几个异常,抛出几个,就catch几个。

    紧接着我们来说下java项目中常用的异常处理情况。

    1、java.lang.NullPointerException(空指针异常)

    发生该情况一般是字符串变量未初始化,数组或数组元素未初始化,类对象未初始化或者是对象不存在等。

    解决方案:

    1、对字符串变量使用if语句判断是否为空,为空抛出一个异常。

    2、数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化, 依然是空的,所以还需要对每个元素都进行初始化。

    3、对类进行初始化的检查,若未初始化抛出异常告知调用者。

    4、避免去调用可能为null的对象的方法(静态方法除外)。

    5、借助一些工具类,比如Apache StringUtils。

    2、 java.lang.ClassNotFoundException(指定的类不存在)

    这个问题比较容易解决,解决方案:

    1、考虑一下类的名称和路径是否正确。

    2、缺包,这时只要下载并导入相应的包即可;当我们已经把包导入的时候,又报了这种错误的情况下,就需要开启自己的编辑器去调整设置了;在使用tomcat的时候,先检查lib中是否导入了jar。

    3、对类名和包名验证,类名验证代码如下:

    package exception;
    
    public class test {
     public static void main(String[] args) {
      try {
       Class.forName("exception.Mytest"); 
    }
      catch (ClassNotFoundException e) { e.printStackTrace(); }
    }
    }

    解决包名错误时,可以在编译时,加上【   -d .   】这样可以把当前的目录加入到classpath中。

    3、 java.lang.NumberFormatException(字符串转换为数字异常)

    这个错误就是字符串中出现非数字型字符时,如(123#456)转换为数字时发生异常;除此之外,如果字符串转换为数字时超过了类型的范围(比如string转int和string转double),也会出现这个错误。解决该问题的方法就是在转换之前先对字符串进行检查。

    解决方案:以如下代码为例

    版权声明:此代码为CSDN博主「morethansea」的原创,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/morethansea/article/details/51456580

    package shiyan6;
    
    import java.util.*;
    
    public class demo1 {
        //千万别把类名写成 NumberFormatException 
    
        public static void main(String[] args){
            Scanner input = new Scanner(System.in);
            boolean inputinteger= true;
            System.out.println("Please input two integer:");
    
                do{ 
    
                    try {
                        //输入的数字或字母等都先当成String类型储存
                        String number1 = input.nextLine();
                        String number2 = input.nextLine();
    
                        int n1 = Integer.parseInt(number1);
                        int n2 = Integer.parseInt(number2);
                        //不可以可以转化成整数就会产生想要的异常
                        //显示结果
                        System.out.println("The sum of the two integer is:"+(n1+n2) );
                        inputinteger = false;//没错就退出
                    } 
                    catch (NumberFormatException e) {
                        System.out.println("NumberFormatException!Try to input again:please input the integer!");
                    }
    
                }while(inputinteger);//输入不对继续输入
    
        }
    }

    上述代码就对该异常进行了捕捉和处理,并给出了提示信息,当然自己也可以自定义异常类进行对字符串的判断。

    4、java.lang.IndexOutOfBoundsException(数组下标越界异常)

    这个我们应该特别熟悉,处理方法也较为简单,这里简单说下我自己的思路:

    1、定义一个函数判断输入的数字是否大于数组长度,若大于则抛出一个异常并捕获,用printStackTrace()(jvm默认的异常处理机制就是调用异常对象的这个方法)告诉调用者出错的位置和原因。

    在这里引用下毕向东老师的源码:

    class Demo
    {
        public int show(int index)throws ArrayIndexOutOfBoundsException
        {
    
            if(index<0)
                throw new ArrayIndexOutOfBoundsException("越界啦!!");
            int[] arr = new int[3];
            return arr[index];
        }
    }
    
    
    class ExceptionDemo5 
    {
        public static void main(String[] args) 
        {
            Demo d = new Demo();
            try
            {
                
                int num = d.show(-1);
                System.out.println("num="+num);
            }
            catch (ArrayIndexOutOfBoundsException e)
            {
                System.out.println(e.toString());
    
    //            return ;
    //            System.exit(0);//退出jvm。
            }
            finally//通常用于关闭(释放)资源。
            {
                System.out.println("finally");
            }
    
            System.out.println("over");
    
        }
    }

    2、循环输出数组的内容尽量用数组名.length来代替变量。

    5、java.lang.IllegalArgumentException(方法的参数错误)

    这个一般是由参数传递类型或少传参导致的,在调用传参方法时,可先对参数类型和个数进行检查,若发现错误可及时告诉调用者,由调用者进行问题的处理。

    所以在调用带有参数的方法时,请注意传递的参数或个数是否正确。

    6、java.lang.IllegalAccessException(没有访问权限)

    当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常。对程序中用了Package的情况下要注意这个异常。

    处理办法:根据异常找到方法,修改方法的访问权限,一般是改为public。

    7、java.lang.ArithmeticException(数学运算异常)

    除数为0时会报出该错误,解决方法:避免除数为0。这个错误解读为“出现异常的运算条件”,除了除数为0的情况之外,可能还有其他的异常情况,到时具体情况具体分析。这里引用下王建民老师的代码对该异常进行处理。

    package test;
    
    import javax.swing.*;
    
    class AboutException {
       public static void main(String[] a) 
       {
          int i=1, j=0, k;
        try
        {
            
            k = i/j;    // Causes division-by-zero exception
            //throw new Exception("Hello.Exception!");
        }
        
        catch ( ArithmeticException e)
        {
            System.out.println("被0除.  "+ e.getMessage());
        }
        
        catch (Exception e)
        {
            if (e instanceof ArithmeticException)
                System.out.println("被0除");
            else
            {  
                System.out.println(e.getMessage());
                
            }
        }
    
        
        finally
         {
                 JOptionPane.showConfirmDialog(null,"OK");
         }
            
      }
    }

    8、java.lang.ClassCastException(数据类型转换异常)

    当试图将对某个对象强制执行向下转型,但该对象又不可转换又不可转换为其子类的实例时将引发该异常,如下列代码。

    Object obj = new Integer(0);

    String str = obj;

    解决方案:

    在进行强制类型转换时容易发生该错误,在进行转换前先对类型进行判别,规避错误。

    9、javaweb页面异常,你所访问的资源不存在或者不愿被访问(这里只针对自己出现的错误)

    出现这种错误的原因一般为JSP文件放在xml目录中或自己的数据库未创建相关表和数据库名称,还有可能数据库密码错误。

    解决方案:依次排除这些选项即可。

    10、 java.lang.FileNotFoundException(文件未找到异常)

    当程序试图打开一个不存在的文件进行读写时将会引发该异常。该异常由FileInputStream,FileOutputStream,RandomAccessFile的构造器声明抛出,即使被操作的文件存在,但是由于某些原因不可访问,比如打开一个只读文件进行写入,这些构造方法仍然会引发异常。

    11、 java.lang.EOFException(文件已结束异常)

    当程序在输入的过程中遇到文件或流的结尾时,引发异常。因此该异常用于检查是否达到文件或流的结尾

    12、java.lang.InstantiationException(实例化异常)

    当试图通过Class的newInstance()方法创建某个类的实例,但程序无法通过该构造器来创建该对象时引发。Class对象表示一个抽象类,接口,数组类,基本类型 。该Class表示的类没有对应的构造器。

    13、java.lang.InterruptedException(被中止异常)

    当某个线程处于长时间的等待、休眠或其他暂停状态,而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。

    14、java.lang.CloneNotSupportedException (不支持克隆异常)

    当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。

    15、java.lang.OutOfMemoryException (内存不足错误)

    当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。

    16、java.lang.NoClassDefFoundException (未找到类定义错误)

    当Java虚拟机或者类装载器试图实例化某个类,而找不到该类的定义时抛出该错误。

    17、SecturityException(违背安全原则异常)

    18、SQLException(操作数据库异常)

    19、IOException(输入输出异常)

    20、SocketException(通信异常)

    21、java.lang.Error(错误)

    错误,是所有错误的基类,用于标识严重的程序运行问题,这些问题通常描述一些不应该被应用程序捕获的反常情况。

    原因:对系统所访问外部资源,未执行关闭操作,导致外部资源大量浪费,最终可能导致系统无法正常运行;对系统所访问的外部资源关闭次数太多,外部系统无法正常处理;系统访问的外部资源出现异常情况。

    解决方法:访问外部资源之前,首先检查该资源(如数据库)是否可正常连接或操作;访问外部资源时,如果进行了连接,一定要关闭操作,并且仅进行一次关闭操作;尽量在同一操作中共享外部资源,以减少该操作对资源的浪费,提高程序的执行效率。

  • 相关阅读:
    加载图片出现403的问题
    js字符串首字母大写的不同写法
    vue中使用两个window.onresize问题解决
    vue备用
    vue注册全局组件
    Java中Timer的用法
    笔记本设置wifi热点
    UVA 11401 Triangle Counting
    数论专题---除法表达式之高精度运算,扩展欧几里得算法
    能被2、3、4、5、6、7、8、9整除数的特征
  • 原文地址:https://www.cnblogs.com/weixiao1717/p/11784446.html
Copyright © 2011-2022 走看看