• C++、Java和C#中的异常处理


    C++中异常:
    1、可以抛出任何异常。虽然标准C++定义了std::exception类,但throw的对象可以是任何对象。包括int、char*等。例如:

    throw 100;

    try {
     
    // do something 
    }
     catch (int num) {
     
    // do something 
    }

    但是,C++标准库中抛出的所有异常,都是派生自std::exception类。
    std::exception定义如下:

    class exception {
        
    public:
            exception( );
            exception(
    const char *const&);
            exception(
    const char *const&int);
            exception(
    const exception&);
            exception
    & operator=(const exception&);
            
    virtual ~exception( );
            
    virtual const char *what( ) const;
    }
    ;


    2、标准C++中,是没有finally子句。熟悉Java和C#的朋友,也许会觉得奇怪!没有finally子句,使用的确不方便。

    3、C++中,函数的声明,缺省时可以抛出任何异常的,也可以使用异常规范来约束函数抛出的异常,如:

    //可以抛出任何异常
    void f() {
     
    throw 100;
    }


    //描述该函数不会抛出任何异常
    void f() throw() {
    }


    //描述该函数会抛出int或者char*类型的异常
    void f() throw(intchar*{
        
    // do something 
    }

    但是,C++中的异常规范不是很可靠。如下的代码也是可以编译通过的,但是编译器会给出警告。

    void f() throw(intchar*{
        
    throw "100";
    }


    4、C++的异常可以派生自多个异常基类。这一个特性使得难以分类的异常容易处理,例如网络文件的异常:

    class file_exception {}
    class network_exception {}
    class newwork_file_exception : public file_exception, public network_exception {}


    5、捕捉所有异常的语法。C++中,不是单根继承的,所以你不能,如同Java或者C#那样,通过捕捉某个基类来捕捉所有的异常。

    try {
     
    // do something 
    }
     catch (//捕捉所有的异常
     
    // do something 
    }

    总结,C++中,命名空间和异常规范是作为针对大规模程序设计而引入的特性。但是由于C++中没有垃圾收集机制,异常造成了资源管理变得非常复杂。在C++中,编写异常安全的代码,是十分困难的。



    Java中的异常:

    1、可以抛出任何派生自了Throwable的类。Throwable类的定义如下:

    public class Throwable implements Serializable {
     
    public Throwable();
     
    public Throwable(String message);
     
    public Throwable(String message, Throwable cause); //@since  1.4
     public Throwable(Throwable cause); //@since  1.4
     public String getMessage();
     
    public String getLocalizedMessage(); //@since   JDK1.1
     public Throwable getCause(); //@since 1.4
     public synchronized Throwable initCause(Throwable cause); //@since  1.4
     public String toString();
     
    public void printStackTrace();
     
    public void printStackTrace(PrintStream s);
     
    public void printStackTrace(PrintWriter s); //@since   JDK1.1
     private void printStackTraceAsCause(PrintWriter s,
                                            StackTraceElement[] causedTrace);
     
    public synchronized native Throwable fillInStackTrace(); 
      
    public StackTraceElement[] getStackTrace(); //@since  1.4
      public void setStackTrace(StackTraceElement[] stackTrace); //@since  1.4
    }

    Throwable下分Exception和Error。

    public class Exception extends Throwable {}
    public class Error extends Throwable {}

    而Exception中,有一个特别的派生类,RuntimeException,如下:
    public class RuntimeException extends Exception {}
    类图如下:



    2、Java中,也使用异常规范,并且在整个基础类库中都使用。Java是基于JVM运行,但是JVM本身就抛出异常,也就是,所有的方法都可能抛出异常。因此,Java编译器编译不检查Error和RuntimeException。与C++不同,没有异常规范,缺省不允许抛出任何非RuntimeException和Error的异常。如下:

    public void f() {
     
    throw new RuntimeException(); //正确
    }


    public void f() {
     
    throw new Error(); //正确
    }

    以下的代码编译出错

    public void f() {
     
    throw new Exception(); 
    }

    使用异常规范的正确例子:

    public WfException extends Exception {}

    public void f() throws WfException {
     
    throw new WfException();
    }


    3、Throwable、Exception、RuntimeException中部分成员,是在不同的JDK版本中添加的,编写代码的时候需要注意。如下的代码不能在JDK 1.3中编译通过:

    public void f() throws WfException {
     
    try {
      
    // do something 
     }
     catch (Exception e) {
      
    throw new WfException ("", e);
     }

    }


    4、Java中的try语法,包括finally子句。如下:

    try {
     
    // do something 
    }
     catch (Exception e) {
     
    // do something 
    }
     finally {
     
    // do something 
    }

    C#中的异常:
    1、C#异常的局限性。C#是基于CLR运行的,由于CLR需要支持多种语言,其异常的实现受到了较大的局限。一个重要的特征就是没有异常规范,很多人对此很失望!Anders Hejlsberg曾专门发表过文章,说明为什么C#不支持异常规范,说得也很有道理。但是,没有异常规范的C#,变得简单,但也更容易犯错误,在这一点上,我更喜欢Java,而不喜欢C#的方式。没有异常规范,编译器就不会帮我们检查代码,是否做了try ... catch处理。

    2、异常的结构。在.NET Framework中,所有的异常派生自System.Exception基类。其下有两个子类:SystemException和ApplicationException。自行编写异常类,不建议直接派生自Exception类,而是应该派生自ApplicationException。

    3、C#犹如Java,也支持finally的写法。如:

    try 
    {
     
    // do something 
    }
     
    catch (Exception e) 
    {
     
    // do something 
    }
     
    finally 
    {
     
    // do something 
    }
  • 相关阅读:
    LeetCode 40. 组合总和 II(Combination Sum II)
    LeetCode 129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)
    LeetCode 60. 第k个排列(Permutation Sequence)
    LeetCode 47. 全排列 II(Permutations II)
    LeetCode 46. 全排列(Permutations)
    LeetCode 93. 复原IP地址(Restore IP Addresses)
    LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)
    LeetCode 59. 螺旋矩阵 II(Spiral Matrix II)
    一重指针和二重指针
    指针的意义
  • 原文地址:https://www.cnblogs.com/jobs/p/25688.html
Copyright © 2020-2023  润新知