std::exception vs java.lang.Exception

2019-05-25 22:32:48 浏览数 (1)

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433723

我们知道std::exceptionjava.lang.Exception分别是C 和Java语言的大部分异常类型的基类。如果我们要定义一个自己的异常类型,一般会以这两个类做基类来写自己的类代码。这是我在写C 和Java代码的时的理解,觉得这俩货是一样的。

最近在研究Java到C 代码自动转换时(将项目中的一部分java代码自动翻译成C 代码),才发现在细节上这两个类还是有区别的。

下面是java中java.lang.Exception类的定义,

可以看到除了默认构造函数之外,还有另外三个构造函数。再看std::exception,在C 标准定义中除了默认构造函数外,只有一个构造函数。

http://www.cplusplus.com/reference/exception/exception/exception/

而实际gcc中对std::exception的定义就只有默认构造函数了(参见后面gcc的std::exception代码)

区别,这就是区别,所以在C 下 std::exception("hello")这样的写法是不对的,因为没有对应的构造函数。所以原本Java代码中throw new Exception("hello");这样的语句,就不能直接翻译成throw new std::exception("hello");

既然std::exception不能用来替代Java的java.lang.Exception,那么替代方案就是std::logic_error来替代java.lang.Exception

虽然不清楚为什么std::exception要做这样的定义,算不算个bug,但是使用起来确实很不方便啊。

大概microsoft发现了这个问题实在忍不了了,所以msvc中的std::exception就在标准C 基础上做了扩充,增加了exception(char const* const _Message)exception(exception const& _Other)构造函数(参见后面的代码)。

java中java.lang.Exception类代码

代码语言:javascript复制
/*
 * %W% %E%
 *
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang;

/**
 * The class <code>Exception</code> and its subclasses are a form of 
 * <code>Throwable</code> that indicates conditions that a reasonable 
 * application might want to catch.
 *
 * @author  Frank Yellin
 * @version %I%, %G%
 * @see     java.lang.Error
 * @since   JDK1.0
 */
public class Exception extends Throwable {
    static final long serialVersionUID = -3387516993124229948L;

    /**
     * Constructs a new exception with <code>null</code> as its detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     */
    public Exception() {
    super();
    }

    /**
     * Constructs a new exception with the specified detail message.  The
     * cause is not initialized, and may subsequently be initialized by
     * a call to {@link #initCause}.
     *
     * @param   message   the detail message. The detail message is saved for 
     *          later retrieval by the {@link #getMessage()} method.
     */
    public Exception(String message) {
    super(message);
    }

    /**
     * Constructs a new exception with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * <code>cause</code> is <i>not</i> automatically incorporated in
     * this exception's detail message.
     *
     * @param  message the detail message (which is saved for later retrieval
     *         by the {@link #getMessage()} method).
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A <tt>null</tt> value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Exception(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructs a new exception with the specified cause and a detail
     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
     * typically contains the class and detail message of <tt>cause</tt>).
     * This constructor is useful for exceptions that are little more than
     * wrappers for other throwables (for example, {@link
     * java.security.PrivilegedActionException}).
     *
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A <tt>null</tt> value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Exception(Throwable cause) {
        super(cause);
    }
}

gcc中std::exception的代码

代码语言:javascript复制
  /**
   *  @brief Base class for all library exceptions.
   *
   *  This is the base class for all exceptions thrown by the standard
   *  library, and by certain language expressions.  You are free to derive
   *  your own %exception classes, or use a different hierarchy, or to
   *  throw non-class data (e.g., fundamental types).
   */
  class exception
  {
  public:
    exception() _GLIBCXX_USE_NOEXCEPT { }
    virtual ~exception() _GLIBCXX_USE_NOEXCEPT;

    /** Returns a C-style character string describing the general cause
     *  of the current error.  */
    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
  };

msvc中std::exception的代码

代码语言:javascript复制
class exception
{
public:

    exception() throw()
        : _Data()
    {
    }

    explicit exception(char const* const _Message) throw()
        : _Data()
    {
        __std_exception_data _InitData = { _Message, true };
        __std_exception_copy(&_InitData, &_Data);
    }

    exception(char const* const _Message, int) throw()
        : _Data()
    {
        _Data._What = _Message;
    }

    exception(exception const& _Other) throw()
        : _Data()
    {
        __std_exception_copy(&_Other._Data, &_Data);
    }

    exception& operator=(exception const& _Other) throw()
    {
        if (this == &_Other)
        {
            return *this;
        }

        __std_exception_destroy(&_Data);
        __std_exception_copy(&_Other._Data, &_Data);
        return *this;
    }

    virtual ~exception() throw()
    {
        __std_exception_destroy(&_Data);
    }

    virtual char const* what() const
    {
        return _Data._What ? _Data._What : "Unknown exception";
    }

private:

    __std_exception_data _Data;
};

0 人点赞