錯誤和錯誤處理代表一種 API 類別。與錯誤處理相關的錯誤非常普遍,所以它們應該擁有自己的特殊領域。如同「API 濫用」,有兩種方法可以引入與錯誤相關的安全漏洞:最常見的一種方法是不當處理錯誤 (或根本沒有處理)。第二種是產生錯誤,這些錯誤不是給的資訊太多 (給可能的攻擊者),就是問題難以處理。
NullPointerException
不是個好方法。NullPointerException
: NullPointerException
異常狀況來提醒出現錯誤情況。NullPointerException
。
try {
mysteryMethod();
}
catch (NullPointerException npe) {
}
NullReferenceException
不是個好方法。NullReferenceException
: NullReferenceException
異常狀況來提醒出現錯誤情況。NullReferenceException
。
try {
MysteryMethod();
}
catch (NullReferenceException npe) {
}
finally
區塊中回傳,會導致異常遺失。finally
區塊中的回傳指令,會導致 try 區塊中所拋出的任意異常遭丟棄。doMagic
方法,同時將 true
參數傳送給該方法,會導致拋出 MagicException
異常,該異常將不會傳送給呼叫者。finally
區塊中的回傳指令,會導致異常遭丟棄。
public class MagicTrick {
public static class MagicException extends Exception { }
public static void main(String[] args) {
System.out.println("Watch as this magical code makes an " +
"exception disappear before your very eyes!");
System.out.println("First, the kind of exception handling " +
"you're used to:");
try {
doMagic(false);
} catch (MagicException e) {
// An exception will be caught here
e.printStackTrace();
}
System.out.println("Now, the magic:");
try {
doMagic(true);
} catch (MagicException e) {
// No exception caught here, the finally block ate it
e.printStackTrace();
}
System.out.println("tada!");
}
public static void doMagic(boolean returnFromFinally)
throws MagicException {
try {
throw new MagicException();
}
finally {
if (returnFromFinally) {
return;
}
}
}
}
finally
區塊中回傳,會導致異常遺失。finally
區塊中的回傳陳述式,會導致 try 區塊中所拋出的任何異常遭丟棄。doMagic
,同時將 True
參數傳遞給該方法,會導致拋出 exception
異常,該異常將不會傳送給呼叫者。finally
區塊中的回傳陳述式,會導致異常遭丟棄。"disappear before your very eyes!" . PHP_EOL;
echo "First, the kind of exception handling " .
"you're used to:" . PHP_EOL;
try {
doMagic(False);
} catch (exception $e) {
// An exception will be caught here
echo $e->getMessage();
}
echo "Now, the magic:" . PHP_EOL;
try {
doMagic(True);
} catch (exception $e) {
// No exception caught here, the finally block ate it
echo $e->getMessage();
}
echo "Tada!" . PHP_EOL;
function doMagic($returnFromFinally) {
try {
throw new Exception("Magic Exception" . PHP_EOL);
}
finally {
if ($returnFromFinally) {
return;
}
}
}
?>
ThreadDeath
錯誤,有問題的執行緒可能並未真正停止。ThreadDeath
錯誤。如果出現 ThreadDeath
錯誤,請務必重新拋出該錯誤來真正停止執行緒。拋出 ThreadDeath
的用意為停止執行緒。如果接收 ThreadDeath
,就會導致執行緒持續執行並造成意外行為,因為原來拋出 ThreadDeath
的使用者想停止該執行緒。ThreadDeath
,但並未重新拋出。
try
{
//some code
}
catch(ThreadDeath td)
{
//clean up code
}
finally
區塊內使用 throw
指令會透過 try-catch-finally
中斷邏輯次序。finally
區塊永遠會在對應 try-catch
區塊後執行,而且通常用來釋放已配置資源,例如檔案控制碼或資料庫指標。在 finally
區塊中拋出異常,可以略過重要的清除程式碼,這是因為將中斷正常程式執行。 FileNotFoundException
時,會略過呼叫 stmt.close()
。
public void processTransaction(Connection conn) throws FileNotFoundException
{
FileInputStream fis = null;
Statement stmt = null;
try
{
stmt = conn.createStatement();
fis = new FileInputStream("badFile.txt");
...
}
catch (FileNotFoundException fe)
{
log("File not found.");
}
catch (SQLException se)
{
//handle error
}
finally
{
if (fis == null)
{
throw new FileNotFoundException();
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (SQLException e)
{
log(e);
}
}
}
}
javax.net.ssl.SSLHandshakeException
、javax.net.ssl.SSLKeyException
和 javax.net.ssl.SSLPeerUnverifiedException
都會傳達與 SSL 連線相關的重要錯誤。如果沒有明確地處理這些錯誤,連線可能會處於一種非預期且潛在不安全的狀態。