java函数定义抛出异常_当从本地Java方法抛出C++异常时会发生什么?

Java编译器不理解C++异常,所以您必须同时使用Java和C++异常。幸运的是,这并不太复杂。首先,我们有一个C++异常,告诉我们是否发生了Java异常。

#include

//This is how we represent a Java exception already in progress

struct ThrownJavaException : std::runtime_error {

ThrownJavaException() :std::runtime_error("") {}

ThrownJavaException(const std::string& msg ) :std::runtime_error(msg) {}

};

inline void assert_no_exception(JNIEnv * env) {

if (env->ExceptionCheck()==JNI_TRUE)

throw ThrownJavaException("assert_no_exception");

}

我们也有一个C++异常来抛出新的Java异常:

//used to throw a new Java exception. use full paths like:

//"java/lang/NoSuchFieldException"

//"java/lang/NullPointerException"

//"java/security/InvalidParameterException"

struct NewJavaException : public ThrownJavaException{

NewJavaException(JNIEnv * env, const char* type="", const char* message="")

:ThrownJavaException(type+std::string(" ")+message)

{

jclass newExcCls = env->FindClass(type);

if (newExcCls != NULL)

env->ThrowNew(newExcCls, message);

//if it is null, a NoClassDefFoundError was already thrown

}

};

void swallow_cpp_exception_and_throw_java(JNIEnv * env) {

try {

throw;

} catch(const ThrownJavaException&) {

//already reported to Java, ignore

} catch(const std::bad_alloc& rhs) {

//translate OOM C++ exception to a Java exception

NewJavaException(env, "java/lang/OutOfMemoryError", rhs.what());

} catch(const std::ios_base::failure& rhs) { //sample translation

//translate IO C++ exception to a Java exception

NewJavaException(env, "java/io/IOException", rhs.what());

//TRANSLATE ANY OTHER C++ EXCEPTIONS TO JAVA EXCEPTIONS HERE

} catch(const std::exception& e) {

//translate unknown C++ exception to a Java exception

NewJavaException(env, "java/lang/Error", e.what());

} catch(...) {

//translate unknown C++ exception to a Java exception

NewJavaException(env, "java/lang/Error", "Unknown exception type");

}

}

通过上述功能,在C++代码中很容易使用Java/C++混合异常,如下所示。

extern "C" JNIEXPORT

void JNICALL Java_MyClass_MyFunc(JNIEnv * env, jclass jc_, jstring param)

{

try { //do not let C++ exceptions outside of this function

//YOUR CODE BELOW THIS LINE. HERES SOME RANDOM CODE

if (param == NULL) //if something is wrong, throw a java exception

throw NewJavaException(env, "java/lang/NullPointerException", "param");

do_stuff(param); //might throw java or C++ exceptions

assert_no_exception(env); //throw a C++ exception if theres a java exception

do_more_stuff(param); //might throw C++ exceptions

//prefer Java exceptions where possible:

if (condition1) throw NewJavaException(env, "java/lang/NullPointerException", "condition1");

//but C++ exceptions should be fine too

if (condition0) throw std::bad_alloc("BAD_ALLOC");

//YOUR CODE ABOVE THIS LINE. HERES SOME RANDOM CODE

} catch(...) { //do not let C++ exceptions outside of this function

swallow_cpp_exception_and_throw_java(env);

}

}

如果你真的很有雄心壮志,你就有可能

StackTraceElement[]

得到一个部分stacktrace。基本方法是给每个函数

StackTraceElement

NewJavaException

复制堆栈并将其传递给

setStackTrace

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值