C++、Java和C#中的异常处理
2008-06-09 00:53
555 查看
来源:温少的日志
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(int, char*)
{
// do something
}
但是,C++中的异常规范不是很可靠。如下的代码也是可以编译通过的,但是编译器会给出警告。
void f() throw(int, char*)
{
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 {}
类图如下:
Java divides exceptions in two categories: checked exceptions and unchecked exceptions. Exceptions that are not "checked" by the compiler are called unchecked exceptions; exceptions that are "checked" by the compiler are called checked exceptions. The compiler will not compile a file if it contains a method where a checked exception may occur and the method does not handle the checked exception in a catch block or list it in the method header. The classes
If a checked exception might occur in a method and the method does not have
If
In the following code, neither method
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
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(int, char*)
{
// do something
}
但是,C++中的异常规范不是很可靠。如下的代码也是可以编译通过的,但是编译器会给出警告。
void f() throw(int, char*)
{
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 {}
类图如下:
Java divides exceptions in two categories: checked exceptions and unchecked exceptions. Exceptions that are not "checked" by the compiler are called unchecked exceptions; exceptions that are "checked" by the compiler are called checked exceptions. The compiler will not compile a file if it contains a method where a checked exception may occur and the method does not handle the checked exception in a catch block or list it in the method header. The classes
RuntimeException,
Errorand their subclasses are unchecked exceptions. All other exception classes are checked exceptions.
If a checked exception might occur in a method and the method does not have
catchblock to handle the checked exception, then the checked exception must be declared in the method header using a
throwsclause. For example, if an
IOExceptionmight occur in method
readIntegerand
readIntegerdoesn't handle it, then
readIntegermust have the following header:
public int readInteger() throws IOException { }
If
readIntegerdoes not list
IOExceptionin its
throwsclause, compilation will fail with an error message about checked exceptions. Unchecked exceptions may be listed in a
throwsclause, but the compiler does not require it.
In the following code, neither method
readIntegernor method
main( )catches
IOExceptionso they both list
IOExceptionin their
throwsclauses. When method
mainthrows an
IOException, the exception object is passed to the Java Virtual Machine (JVM). The JVM displays the exception information and terminates the program.
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: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: | import java.io.*; /** * This class provides a method that reads an integer from the * standard input. * * @author author name * @version 1.0.0 */ public class IntegerReaderThrowsException { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdErr = new PrintWriter(System.err, true); private static PrintWriter stdOut = new PrintWriter(System.err, true); /** * Tests method <code>readInteger</code> * * @param args not used * @throws IOException if error reading from standard input. */ public static void main (String[] args) throws IOException { stdOut.println("The value is: " + readInteger()); } /** * Reads an integer from the standard output. * * @return the <code>int</code> value. * @throws IOException if error reading from standard input. */ public static int readInteger() throws IOException { do { try { stdErr.print("Enter an integer> "); stdErr.flush(); return Integer.parseInt(stdIn.readLine()); } catch (NumberFormatException nfe) { stdErr.println("Invalid number format"); } } while (true); } } |
Listing 4 IntegerReaderThrowsException.java |
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
相关文章推荐
- C++、Java和C#中的异常处理
- C++ /python/java /C# 自定义异常处理
- 简单了解C++、Java和C#中的异常处理
- C++、Java和C#中的异常处理
- C、C++、Java语言中异常处理机制浅析
- C++、Java和C#语言在处理“虚拟私有方法”上的差异
- 强制类型转换时的异常处理_java与c++比较
- C++与Java异常处理的区别
- C++、Java和C#语言在处理“虚拟私有方法”上的差异
- C++与Java异常处理的区别
- C、C++、Java语言中异常处理机制浅析
- Java异常处理及与C++的比较--异常分类.检验异常.非检验异常.常见异常
- C#中异常处理和Java的区别
- C++和java异常处理中关于finally的区别
- 简记c、c++、java异常处理机制的区别
- C#和java的异常处理性能对比
- JAVA异常处理 与C++的不同
- 记录一下C++和C#中的字符串处理与编码格式的问题
- 深入理解java异常处理机制
- 异常安全在Java和C#语言中的简化