首页 > 代码库 > 连抛2个异常,第一个是第二个的Cause
连抛2个异常,第一个是第二个的Cause
异常只能抛一个,捕捉到再抛一个,也只是一个异常
看下面的代码,如果你认为执行不到(如果 if 条件满足)执行不到第2个 throwException 就错了 (Jeallybean code)
libcore/luni/src/main/native/libcore_io_Posix.cpp#throwException
146 static void throwGaiException(JNIEnv* env, const char* functionName, int error) { 147 if (errno != 0) { 148 // EAI_SYSTEM should mean "look at errno instead", but both glibc and bionic seem to 149 // mess this up. In particular, if you don't have INTERNET permission, errno will be EACCES 150 // but you'll get EAI_NONAME or EAI_NODATA. So we want our GaiException to have a 151 // potentially-relevant ErrnoException as its cause even if error != EAI_SYSTEM. 152 // http://code.google.com/p/android/issues/detail?id=15722 153 throwErrnoException(env, functionName); 154 // Deliberately fall through to throw another exception... 155 } 156 static jmethodID ctor3 = env->GetMethodID(JniConstants::gaiExceptionClass, 157 "<init>", "(Ljava/lang/String;ILjava/lang/Throwable;)V"); 158 static jmethodID ctor2 = env->GetMethodID(JniConstants::gaiExceptionClass, 159 "<init>", "(Ljava/lang/String;I)V"); 160 throwException(env, JniConstants::gaiExceptionClass, ctor3, ctor2, functionName, error); 161 }
因为这不是 native C++ 自己的exception,而是 native 送给 java 层的 exception
再看下面的函数,如果在有 Pending Exception 的情况下(env->ExceptionOccurred), Pending Exception 将成为当前Exception 的 cause
113 static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor3, jmethodID ctor2, 114 const char* functionName, int error) { 115 jthrowable cause = NULL; 116 if (env->ExceptionCheck()) { 117 cause = env->ExceptionOccurred(); 118 env->ExceptionClear(); 119 } 120 121 ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName)); 122 if (detailMessage.get() == NULL) { 123 // Not really much we can do here. We're probably dead in the water, 124 // but let's try to stumble on... 125 env->ExceptionClear(); 126 } 127 128 jobject exception; 129 if (cause != NULL) { 130 exception = env->NewObject(exceptionClass, ctor3, detailMessage.get(), error, cause); 131 } else { 132 exception = env->NewObject(exceptionClass, ctor2, detailMessage.get(), error); 133 } 134 env->Throw(reinterpret_cast<jthrowable>(exception)); 135 }
再看下面
libcore/luni/src/main/java/java/net/InetAddress.java#getAllByNameImpl
417 } catch (GaiException gaiException) { 418 // If the failure appears to have been a lack of INTERNET permission, throw a clear 419 // SecurityException to aid in debugging this common mistake. 420 // http://code.google.com/p/android/issues/detail?id=15722 421 if (gaiException.getCause() instanceof ErrnoException) { 422 if (((ErrnoException) gaiException.getCause()).errno == EACCES) { 423 throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException); 424 } 425 } 426 // Otherwise, throw an UnknownHostException. 427 String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error); 428 addressCache.putUnknownHost(host, detailMessage); 429 throw gaiException.rethrowAsUnknownHostException(detailMessage); 430 }
检测到GaiException的时候,正好检查 Cause 是否是 ErrnoException
连抛2个异常,第一个是第二个的Cause
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。