亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java:錯誤處理能力差,最后扔進去

Java:錯誤處理能力差,最后扔進去

慕妹3146593 2023-06-21 13:34:28
我有以下代碼正在通過 fortify 運行。為什么它被標記為糟糕的錯誤處理,最后扔進去?private String getResourceContent(String fileName) throws IOException {    try (InputStream resource = ErrorResource.classLoader.getResourceAsStream(fileName)) {        return new String(resource.readAllBytes(), StandardCharsets.UTF_8);    } catch (NullPointerException n) {        throw new ErrorDescriptorException(                String.format("Error loading Error description data from Resource file [%s].", fileName), n);    }}
查看完整描述

3 回答

?
HUX布斯

TA貢獻1876條經驗 獲得超6個贊

解釋

讓我快速引用重要部分:

throw在塊內使用語句finally會破壞 try-catch-finally 的邏輯進程。

在 Java 中,finally 塊始終在相應的 try-catch 塊之后執行,并且通常用于釋放分配的資源,例如文件句柄或數據庫游標。在 finally 塊中拋出異??梢?strong>繞過關鍵的清理代碼,因為正常的程序執行將被中斷。

因此,您可以通過這樣做輕松繞過清理代碼,從而導致資源泄漏。

雖然在代碼中不直接可見,但實際上有一個隱藏?finally塊,因為您使用的是try-with-resources,它會自動關閉 finally 塊中的資源。


例子

這是官方文檔中的示例:

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) {

? ? ? ? ? ? // This bypasses cleanup code

? ? ? ? ? ? throw new FileNotFoundException();

? ? ? ? }


? ? ? ? if (stmt != null) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? // Not executed if the exception is thrown

? ? ? ? ? ? ? ? stmt.close();

? ? ? ? ? ? }

? ? ? ? ? ? catch (SQLException e) {

? ? ? ? ? ? ? ? log(e);

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

拋出時繞過stmt.close()對的調用。FileNotFoundException


筆記

為什么要檢查是否null使用 aNullPointerException而不是基本的if-else?很少有正當理由去抓捕NullPointerException。做就是了:

try (InputStream resource = ErrorResource.classLoader.getResourceAsStream(fileName)) {

? ? if (resource == null) {

? ? ? ? // TODO Throw your exception here

? ? }

? ? return new String(resource.readAllBytes(), StandardCharsets.UTF_8);

}

通過告知無法找到資源的確切原因,它也可能有助于改進錯誤消息。



查看完整回答
反對 回復 2023-06-21
?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

考慮以下代碼,它大致基于您的代碼:


String throwing(InputStream inputStream) throws IOException {

    try (InputStream resource = inputStream) {

        return "good";

    } catch (NullPointerException n) {

        return "bad";

    }

}

你看,這里沒有拋出異常。盡管如此,你還是無法移除這個throws IOException部分——那是怎么回事?好吧,InputStream#close()可以拋出它,它將位于finallytry-with-resources 語句創建的隱式塊中。我想您對此無能為力,它看起來像是 Fortify 誤報。


查看完整回答
反對 回復 2023-06-21
?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

除了工具中的誤導性消息之外,您的代碼中實際上存在糟糕的錯誤處理,原因有多種:

  • 捕捉 NPE 是非常糟糕的做法。要么它是一個錯誤(某些東西是 null 并且不應該),要么你的代碼缺少檢查if (whatever == null)和相應的代碼來處理這種預期情況

  • 假設這個 NPE 具有您在新 Exception 中表達的確切含義,只是猜測

換句話說:在沒有更多信息的情況下,不清楚您的工具到底抱怨什么。但是:不需要工具來理解:這是糟糕的錯誤處理。

除此之外,此類工具通常會提供有關其警告的某種信息。意思是:該警告可能帶有一個“錯誤 ID”,您應該能夠在您的工具文檔中查找該“錯誤 ID”以獲得進一步的解釋。


查看完整回答
反對 回復 2023-06-21
  • 3 回答
  • 0 關注
  • 207 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號