C++的和Java的异常机制

    程序总会出现异常的,需要我们去处理。C++和JAVA都有自己异常机制,我们应该遵循着去处理异常。那它们的异常机制有何异同呢?

    要注意一点:异常机制处理异常是要付出代价的,即异常处理的代码比无异常处理的要慢好多倍。

JAVA的异常机制

    在面向对象的世界里,一切都是对象,JAVA的异常也不例外。API中异常类的“始祖”是 Throwable  类,有 Exception 类和 Error 类直接继承Throwable  。Error是很严重的,是不可挽救的,我们一般是通过继承Throwable  或Exception 来定义自己的异常类。

    先看看API(这里是从1.5摘抄的)里的两个异常类是怎样的?

import   java.io. * ;
public   class  Throwable  implements  Serializable  {
    
/** use serialVersionUID from JDK 1.0.2 for interoperability */
    
private static final long serialVersionUID = -3042686055658047285L;

    
/**
     * Native code saves some indication of the stack backtrace in this slot.
     
*/

    
private transient Object backtrace; 
    
private String detailMessage;
    
private Throwable cause = this;
    
private StackTraceElement[] stackTrace;
    
    
public Throwable() {
        fillInStackTrace();
    }


    
public Throwable(String message) {
        fillInStackTrace();
        detailMessage 
= message;
    }


    
public Throwable(String message, Throwable cause) {
        fillInStackTrace();
        detailMessage 
= message;
        
this.cause = cause;
    }


    
public String getLocalizedMessage() {
        
return getMessage();
    }


    
public Throwable getCause() {
        
return (cause==this ? null : cause);
    }


    
public synchronized Throwable initCause(Throwable cause) {
        
if (this.cause != this)
            
throw new IllegalStateException("Can't overwrite cause");
        
if (cause == this)
            
throw new IllegalArgumentException("Self-causation not permitted");
        
this.cause = cause;
        
return this;
    }


    
public String toString() {
        String s 
= getClass().getName();
        String message 
= getLocalizedMessage();
        
return (message != null? (s + "" + message) : s;
    }


    
private synchronized StackTraceElement[] getOurStackTrace() {
        
// Initialize stack trace if this is the first call to this method
        if (stackTrace == null{
            
int depth = getStackTraceDepth();
            stackTrace 
= new StackTraceElement[depth];
            
for (int i=0; i < depth; i++)
                stackTrace[i] 
= getStackTraceElement(i);
        }

        
return stackTrace;
    }

//......省略了一些
}

注意一点:异常类是可串行化的。

public   class  Exception  extends  Throwable {
    
static   final   long  serialVersionUID  =   - 3387516993124229948L ;

    
public  Exception() {
    
super ();
    }

    
public  Exception(String message) {
    
super (message);
    }

    
public  Exception(String message, Throwable cause) {
        
super (message, cause);
    }

    
public  Exception(Throwable cause) {
        
super (cause);
    }
}

一个简单例子:

public   class  MyException  extends  Exception
{
MyException(String str)
    
{
    
super(str);
    }

}


public    class  MyTest
{
public void f()throws MyException
    
{
    
throw new MyException("f() exception");
    }

}

public   class  Main
{
    
public static void main(String[]args)
    
{
        
try
        
{
            
new MyTest().f();
        }
catch(MyException me)
        
{
            System.out.println(me);
        }
finally
        
{System.out.println("finally");
        }

    }

}

    如果可能发生多种异常时,可用多个catch语句捕捉不同类型的异常,从第一个catch开始匹配异常,如果异常是该类或该类的子类,则匹配。如果要匹配所有的异常,则在catch中捕捉 Throwable 类,因为其它所有异常类都是其子类,都可匹配。其中 finally块是程序必然会执行的块,除非JVM突然退出了。

C++的异常机制

    在C的时候,错误处理要 setjmp() / longjmp() 通过。而C++里, setjmp() / longjmp() 已经不能用了。C++的异常可以是类,也可以是基本类型(如int)。在标准库中,也存在exception类。但是,C++并没有要求我们自定义的异常要继承某个类。

一个简单例子:

#include < iostream >
using   namespace  std;

#ifndef NULL
#define  NULL 0
#endif
class  MyException
{
      
const char * const msg;
      
public:
             MyException(
const char* const _msg=NULL):msg(_msg){};
             
void print()
             
{
                  cout
<<msg<<endl;
             }

}
;
void  f()
{
     
throw MyException("something bad happened");
}


int  main()
{
    
try
    
{
    f();
    }
catch(MyException me)
    
{
    me.print();
    }

  system(
"pause");
  
return 0;
}

    C++的异常捕捉匹配和JAVA的基本相同,只是C++没有 finally 块。要捕捉所有异常的方法是用 catch(...) 语句。

    以上所述都只是JAVA和C++的异常机制的皮毛。对JAVA的异常,觉得自己理解得还可以,懂得什么是捕捉,什么是抛出异常、传播异常和包装异常等。但是对C++的异常,可以说是刚刚接触,刚才看了 Thinking in C++  异常处理的一章。想起JAVA的异常机制,就作个对比,写个笔记。

 

你可能感兴趣的:(C/C++,java)