自定义异常总结

时间:2022-08-30 08:40:11
3. 不要忽略异常

  当一个 API 方法抛出 checked exception 时,它是要试图告诉你你需要采取某些行动处理它。如果它对你来说没什么意义,不要犹豫,直接转换成 unchecked exception 抛出,千万不要仅仅用空的{}catch 它,然后当没事发生一样忽略它。


摘抄一、面向对象之RuntimeException

Exception有一个特殊的子类异常,ArithmeticException执行时异常

如果在函数内部抛出异常,函数上可以不用声明,编译一样通过1

如果在函数上申明了该异常,调用者可以不用进行处理,编译一样通过。

之所以不用在函数声明,是因为不需要让调用者处理

当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况,希望停止程序后!

对待吗进行修正!

 

自定义异常时:如果该异常的发生,无法在继承进行运算!

就让自定义异常继承RuntimeException.(捕获异常后,可以调用System.exit()退出程序)

面向对象之自定义异常

/*

因为项目中出现了特有的问题

而这些问题并未被Java所描述并封装对象。

所以对于这些特有的问题可以按照Java的对问题封装的思想、

将特有的问题,进行自定义的一场封装

 

自定义异常:

 

需求:在本程序中,对应除数是-1,也是为错误的,是无法进行运算的。,

那么就需要对这个问题进行自定义的描述。

 

当在函数内部出现了throw抛出了异常对象,那么就必须要给对应处理动作

要么在汉函数上申明让调用者处理

要么在函数上声明让调用者处理

 

一般情况下,函数内部出现异常,函数上需要声明

 

发现打印的结果中集中只有异常的名称。却没有异常的信息

因为自定义的异常并未定义信息

 

如何定义异常信息???

因为父类中已经发异常信息的操作已经完成了,

所以子类只要在构造时,将异常信息传给父类通过super语句,

那么就可以直接通过getMassage方法获取自定义的异常信息,

 

自定义异常:

必须是自定义类继承Exception。

 

继承Exception原因:

异常体系有一个特点,因为异常类和异常对象都会抛出

他们就、都具有可抛型。这个可抛型是Throwable这个体系中独有的特点

 

只有这个体系中的类和对象才可以被throws和throw操作!

 

throws和throw和区别:

throws使用在函数上

throw使用在函数内。

throws后面跟着异常类,可以跟多个、用逗号分开。

throw后面跟的是异常对象

 

 

*/

class FuShuException extends Exception //getMassage();

{

     private int value;

     //private String mag;

     FuShuException(String msg)

     {

 

     super(msg);

 

     /*this.msg = msg;

     }

     public String getMessage()

     {

     return msg;*/

     }

     FuShuException(String msg,int value)

     {

     super(msg);

     this.value = value;

     }

     public int getValue()

     {

     return value;

     }

 

}

 

class Demo

{

int div(int a,int b)throws FuShuException//throws定义在函数上

     {

 

     if (b<0)

     {

         throw new FuShuExeption("出现了除数是负数的情况 -----/by fushu",b);//手动通过throw关键字手动抛出自定义异常对象

     }//throw定义在函数内!

     return a/b;

     }

}

 

 

class ExceptionDemo3

{

public static void main(String[] args)

     {

     Demo d = new Demo();

     try

     {

         int x = d.div(4,-1);

         System.out.println("x="+x);

     }

     catch (FuShuException e)

     {

         System.out.println(e.toString());

         //System.out.println("除数出现负数了");

         System.out.println("错误的负数是:"+e.getValue());

     }

 

     System.out.println("over")

     }

}

/*

class Throwable

{

private String message;

Throwable(String message)

     {

     this.message = message;

     }

     public String getMassage()

     {

     return message;

     }

}

class Exception extends Throwable

{

Exception(String massage)

     {

     super(massage);

     }

}

class Person

{

String name;

Person(String name)

     {

     this.name = name;

     }

     public String getName()

     {

     return name();

     }

}

class Student extends Person

{

Student (String name)

     {

     super(name);

     }

}

new Student("lisi")

*/

 

面向对象之RuntimeException

/*

 

Exception有一个特殊的子类异常,ArithmeticException执行时异常

 

如果在函数内部抛出异常,函数上可以不用声明,编译一样通过1

 

如果在函数上申明了该异常,调用者可以不用进行处理,编译一样通过。

 

之所以不用在函数声明,是因为不需要让调用者处理

当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况,希望停止程序后!

对待吗进行修正!

 

 

自定义异常时:如果该异常的发生,无法在继承进行运算!

就让自定义异常继承RuntimeException.

 

对应异常分两种:

1,编译时被检测的异常

2,编译时不被检测的异常(运行是异常,RuntimeException以及子类)

 

*/

 

class FuShuException extends RuntimeException

{

     FuShuException(String msg)

     {

     super.(msg);

     }

}

 

class Demo

{

int div(int a,int b)//throws ArithmeticException

     {

     if (b<0)

      throw new FuShuException("出现的除数为负数");

     if (b==0)

      throw new ArithmeticException("被零除啦");

     return a/b;

}

class ExceptionDemo5

{

public static void main(String[] args)

     {

     Demo d = new Demo();

 

     int x = a.div(4,0);

 

     System.out.println("x="+x);

 

     System.out.println("over")

     }

}

/*

     class Person

     {

     public void checkName(String name)

         {

 

         //if (name.equals("lisi"))//NullPointerException

         if("lisi".equals(name))

              System.out.println("yes");

         else

              Sytem.out.println("no");

        

         }

     }

     main()

     {

     Person p = new Person();

     p.checkName("haha");

     }

     */




http://www.2cto.com/kf/201504/390806.html

Java自定义异常与异常使用最佳实践
异常的分类
1. 非运行时异常(Checked Exception)
Java中凡是继承自Exception但不是继承自RuntimeException的类都是非运行时异常。
2. 运行时异常(Runtime Exception/Unchecked Exception)
RuntimeException类直接继承自Exception类,称为运行时异常。Java中所有的运行时异常都直接或间接的继承自RuntimeException。
Java中所有的异常类都直接或间接的继承自Exception。
异常的处理
一、对应非运行时异常,必须对其进行处理。处理方式有两种:
□使用try…catch…finally语句块进行捕获
□在产生异常的方法所在的方法声明throws Exception
二、对于运行时异常,可以不对其进行处理,也可以对其进行处理。一般情况下都不对其进行处理。
在使用Java API的方法时会产生异常,由于实际的需要,我们需要创建和使用自定义异常。使用全新的异常类,应用到系统程序中。
在介绍自定义异常时,首要先谈谈什么要使用自定义异常,使用自定义异常的好处。创建自定义异常是为了表示应用程序的一些错误类型,为代码可能发生的一个或多个问题提供新的含义;可以显示代码多个位置之间的错误的相似处,也可区分代码运行时可能出现的相似问题的一个或多个错误,或给出应用程序中一组错误的特殊含义。
应用场景
服务器的基本作用是处理与客户机的通信,若使用标准Java API(如java.io和java.net包中的类)来编写服务器,则可使编写的代码在多个位置抛出IOException。在设置服务器、等待客户机连接和获取通讯流时,可抛出IOException,在通信期间及试图断开连接时,也会抛出IOException。简而言之,服务器的各个部分都是引发IOException。
对于服务器而言,这样IOException意义不尽相同。虽然由同一异常类型表示,但与各个异常先关的业务含义存在差异,报告和恢复操作也不相同。所以,可以将一个异常集与服务器配置和启动问题关联,将另一个异常集与客户机通讯的实际行动关联,将第三个异常集与服务器关闭任务关联。使用自定义异常,可采用对应用程序有意义的方式来灵活地表示错误。
为此,我们需要使用自定义异常来定为问题,定位问题与异常实际准确的位置。
自定义异常类过程
1. 多数情况下,只需要继承异常类Exception, 经常需要定义一个或多个构造函数,以在对象中存储错误消息。
扩展:
□类java.lang.Throwable是所有异常类的基类,它包括两个子类:Exception和Error,Exception类用于描述程序能够捕获的异常,如ClassNotFoundException。Error类用于指示合理的应用程序不应该试图捕获的严重问题,如 虚拟机错误VirtualMachineError
□自定义异常类可以继承Throwable类或者Exception类,而不要继承Error类。自定义异常类之间也可以有继承关系
□需要为自定义异常类设计构造方法,以方便构造自定义异常对象。
在继承任何异常时,将自动继承Throwable类的一些标准特性,如:
□错误消息
□栈跟踪
□异常包装

若要在异常中添加附加信息,则可以为类添加一些变量和方法。本例演示的自定义异常没有按照业务类型来命名,而是创建一个通用异常类,以retCd来区别发生异常的业务类型与发生位置,当然对于具体的retCd值,事先必须有具体的规定或说明。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
  * 多数情况下,创建自定义异常需要继承Exception,本例继承Exception的子类RuntimeException
  * @author Mahc
  *
  */
public class CustomerException extends RuntimeException {
 
     private String retCd ;  //异常对应的返回码
     private String msgDes;  //异常对应的描述信息
     
     public CustomerException() {
         super ();
     }
 
     public CustomerException(String message) {
         super (message);
         msgDes = message;
     }
 
     public CustomerException(String retCd, String msgDes) {
         super ();
         this .retCd = retCd;
         this .msgDes = msgDes;
     }
 
     public String getRetCd() {
         return retCd;
     }
 
     public String getMsgDes() {
         return msgDes;
     }
}

2. 声明方法抛出自定义异常。为了使用自定义异常,必须通知调用代码的类:要准备处理这个异常类型。为此,声明一个或多个方法抛出异常。找到异常发生点,新建异常并加上关键字throw。

 

 

?
1
2
3
4
public class TestClass {
 
     public void testException() throws CustomerException {
         try {

//..some code that throws CustomerException

} catch (Exception e) { throw new CustomerException(14000001, String[] strs's length < 4); } } }
3.自定义异常测试操作。

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestCustomerException {
 
     public static void main(String[] args) {
 
         try {
             TestClass testClass = new TestClass();
             testClass.testException();
         } catch (CustomerException e) {
             e.printStackTrace();
             System.out.println(MsgDes   +e.getMsgDes());
             System.out.println(RetCd    +e.getRetCd());
         }
     }
}
以下的自定义异常的最佳实践,摘自网络,经过参考扩展使用。
使用异常的最佳实践
  下面的部分我们列出了客户端代码处理 API 抛出异常的一些最佳实现方法。
  1. 记得释放资源
  如果你正在用 数据库或网络连接的资源,要记得释放它们。如果你使用的 API 仅仅使用 unchecked exception,你应该用完后释放它们,使用 try-final。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void dataAccessCode (){
     Connection conn = null ;
     try {
         conn = getConnection ();
         ..some code that throws SQLException
     } catch (SQLException ex){
         ex.printStacktrace ();
     } finally {
         DBUtil.closeConnection (conn);
     }
}
  class DBUtil{
     public static void closeConnection
         (Connection conn){
         try {
             conn.close ();
         } catch (SQLException ex){
             logger.error (Cannot close connection);
             throw new RuntimeException (ex);
         }
     }
}

DBUtil 是一个关闭连接的工具类。最重要的部分在于 finally,无论异常发不发生都会执行。在这个例子中,finally 关闭了连接,如果关闭过程中有问题发生的话,会抛出一个 RuntimeException。
  2. 不要使用异常作控制流程之用
  生成栈回溯是非常昂贵的,栈回溯的价值是在于调试。在流程控制中,栈回溯是应该避免的,因为客户端仅仅想知道如何继续。
  下面的代码,一个自定义的异常 MaximumCountReachedException,用来控制流程。

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public void useExceptionsForFlowControl () {
     try {
         while ( true ) {
             increaseCount ();
         }
     } catch (MaximumCountReachedException ex) {
     }
     //Continue execution }
  public void increaseCount ()
     throws MaximumCountReachedException {
     if (count >= 5000 )
         throw new MaximumCountReachedException ();
}

useExceptionsForFlowControl()使用了一个无限的循环来递增计数器,直至异常被抛出。这样写不仅降低了代码的可读性,也让代码变得很慢。记住异常仅用在有异常发生的情况。
  3. 不要忽略异常
  当一个 API 方法抛出 checked exception 时,它是要试图告诉你你需要采取某些行动处理它。如果它对你来说没什么意义,不要犹豫,直接转换成 unchecked exception 抛出,千万不要仅仅用空的{}catch 它,然后当没事发生一样忽略它。
  4. 不要 catch 最高层次的 exception
  Unchecked exception 是继承自 RuntimeException 类的,而 RuntimeException 继承自 Exception。如果 catch Exception 的话,你也会 catch RuntimeException。

 

 

?
1
2
3
4
try {
..
} catch (Exception ex){
}

上面的代码会忽略掉 unchecked exception。
  5. 仅记录 exception 一次
  对同一个错误的栈回溯(stack trace)记录多次的话,会让程序员搞不清楚错误的原始来源。所以仅仅记录一次就够了。
   总结:这里是我总结出的一些异常处理最佳实施方法。我并不想引起关于 checked exception 和 unchecked exception 的激烈争论。你可以根据你的需要来设计代码。我相信,随着时间的推移,我们会找到些更好的异常处理的方法的。