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、对类名和包名验证,类名验证代码如下:

 1 package exception;
 2 
 3 public class test {
 4  public static void main(String[] args) {
 5   try {
 6    Class.forName("exception.Mytest"); 
 7   }
 8   catch (ClassNotFoundException e) { e.printStackTrace(); } 
 9   } 
10 }

解决包名错误时,可以在编译时,加上【   -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

 1 package shiyan6;
 2 
 3 import java.util.*;
 4 
 5 public class demo1 {
 6     //千万别把类名写成 NumberFormatException 
 7 
 8     public static void main(String[] args){
 9         Scanner input = new Scanner(System.in);
10         boolean inputinteger= true;
11         System.out.println("Please input two integer:");
12 
13             do{ 
14 
15                 try {
16                     //输入的数字或字母等都先当成String类型储存
17                     String number1 = input.nextLine();
18                     String number2 = input.nextLine();
19 
20                     int n1 = Integer.parseInt(number1);
21                     int n2 = Integer.parseInt(number2);
22                     //不可以可以转化成整数就会产生想要的异常
23                     //显示结果
24                     System.out.println("The sum of the two integer is:"+(n1+n2) );
25                     inputinteger = false;//没错就退出
26                 } 
27                 catch (NumberFormatException e) {
28                     System.out.println("NumberFormatException!Try to input again:please input the integer!");
29                 }
30 
31             }while(inputinteger);//输入不对继续输入
32 
33     }
34 }

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

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

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

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

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

 1 class Demo
 2 {
 3     public int show(int index)throws ArrayIndexOutOfBoundsException
 4     {
 5 
 6         if(index<0)
 7             throw new ArrayIndexOutOfBoundsException("越界啦!!");
 8         int[] arr = new int[3];
 9         return arr[index];
10     }
11 }
12 
13 
14 class ExceptionDemo5 
15 {
16     public static void main(String[] args) 
17     {
18         Demo d = new Demo();
19         try
20         {
21             
22             int num = d.show(-1);
23             System.out.println("num="+num);
24         }
25         catch (ArrayIndexOutOfBoundsException e)
26         {
27             System.out.println(e.toString());
28 
29 //            return ;
30 //            System.exit(0);//退出jvm。
31         }
32         finally//通常用于关闭(释放)资源。
33         {
34             System.out.println("finally");
35         }
36 
37         System.out.println("over");
38 
39     }
40 }

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

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

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

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

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

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

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

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

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

 
 
 1 package test;
 2 
 3 import javax.swing.*;
 4 
 5 class AboutException {
 6    public static void main(String[] a) 
 7    {
 8       int i=1, j=0, k;
 9     try
10     {
11         
12         k = i/j;    // Causes division-by-zero exception
13         //throw new Exception("Hello.Exception!");
14     }
15     
16     catch ( ArithmeticException e)
17     {
18         System.out.println("被0除.  "+ e.getMessage());
19     }
20     
21     catch (Exception e)
22     {
23         if (e instanceof ArithmeticException)
24             System.out.println("被0除");
25         else
26         {  
27             System.out.println(e.getMessage());
28             
29         }
30     }
31 
32     
33     finally
34      {
35              JOptionPane.showConfirmDialog(null,"OK");
36      }
37         
38   }
39 }

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(错误)

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

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

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

 

posted on 2023-10-19 23:48  临江柔  阅读(17)  评论(0编辑  收藏  举报