簡體   English   中英

構造函數可以在Java中引發異常嗎?

[英]Can constructors throw exceptions in Java?

允許構造函數拋出異常嗎?

是的,構造函數可以引發異常。 通常,這意味着新對象可以立即進行垃圾回收(當然,盡管一段時間內可能不會收集到)。 如果“半構造”對象在構造函數中較早可見(例如,通過分配靜態字段或將其自身添加到集合中),則可能會留下痕跡。

在構造函數中引發異常時要注意的一件事:由於調用方(通常)將無法使用新對象,因此構造函數應注意避免獲取非托管資源(文件句柄等),然后引發異常沒有釋放它們。 例如,如果構造函數嘗試打開FileInputStreamFileOutputStream ,但第一個成功,但第二個失敗,則應嘗試關閉第一個流。 如果它是引發異常的子類構造函數,則這將變得更加困難……當然,這都變得有些棘手。 這不是經常出現的問題,但是值得考慮。

是的,他們可以拋出異常。 如果是這樣,它們將僅被部分初始化,如果未完成,則將受到攻擊。

以下來自《 安全編碼指南2.0》

可以通過終結器攻擊來訪問非最終類的部分初始化實例。 攻擊者在子類中重寫受保護的finalize方法,並嘗試創建該子類的新實例。 此嘗試失敗(在上面的示例中,ClassManager中的SecurityManager檢查在ClassLoader的構造函數中引發了安全異常),但是攻擊者只是忽略了任何異常,並等待虛擬機對部分初始化的對象執行最終確定。 發生這種情況時,將調用惡意的finalize方法實現,從而使攻擊者可以訪問此方法,並引用要終結的對象。 盡管僅部分初始化了對象,但攻擊者仍可以在其上調用方法(從而避免了SecurityManager的檢查)。

絕對。

如果構造函數沒有收到有效的輸入,或者無法以有效的方式構造對象,則它沒有其他選擇,只能引發異常並警告其調用者。

是的,它可能引發異常,您也可以在構造函數的簽名中聲明該異常,如下例所示:

public class ConstructorTest
{
    public ConstructorTest() throws InterruptedException
    {
        System.out.println("Preparing object....");
        Thread.sleep(1000);
        System.out.println("Object ready");
    }

    public static void main(String ... args)
    {
        try
        {
            ConstructorTest test = new ConstructorTest();
        }
        catch (InterruptedException e)
        {
            System.out.println("Got interrupted...");
        }
    }
}

是的,允許構造函數拋出異常。

但是,在選擇應將哪些異常(檢查的異常或未檢查的異常)時非常明智。 未經檢查的異常基本上是RuntimeException的子類。

在幾乎所有情況下(對於這種情況我都無法提出例外),您將需要拋出一個已檢查的例外。 原因是未檢查的異常(如NullPointerException)通常是由於編程錯誤(如未充分驗證輸入)引起的。

受檢查的異常提供的好處是,程序員被迫在其實例化代碼中捕獲該異常,從而意識到創建對象實例可能會失敗。 當然,只有代碼審查才能捕獲吞噬異常的不良編程實踐。

是。

構造函數只不過是特殊方法,並且可以像其他任何方法一樣拋出異常。

是的,它可以像其他方法一樣引發異常

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM