簡體   English   中英

檢查異常和初始化程序塊

[英]Checked exception and initializer block

根據JLS:如果命名類的實例變量初始化程序或實例初始值設定項可以拋出一個已檢查的異常類,那么這是一個編譯時錯誤,除非在每個構造函數的throws子句中顯式聲明了該異常類或其一個超類。它的類和類至少有一個顯式聲明的構造函數。

所以,如果我這樣做 -

class A{
 {
  throw new FileNotFoundException();
 }
public A() throws IOException{
    // TODO Auto-generated constructor stub
}
}

這給出了編譯時錯誤“初始化程序必須正常完成”

class A{
 {
  File f=new File("a");
  FileOutputStream fo=new FileOutputStream(f);
  fo.write(3);
 }
public A() throws IOException{
    // TODO Auto-generated constructor stub
}
}

此代碼不顯示任何編譯時錯誤。 即使我在構造函數中聲明了throws子句,為什么前面的代碼不能編譯?

初始化程序實際上可以完成而沒有任何異常應該有一些條件。

在你的情況下,它無法發生。

嘗試:

if(/*condition-to-fail*/) {
    /*Not always, only when something is wrong. Compiler knows that.*/
    throw new FileNotFoundException(); 
}

更新:

以下語句實際上是拋出異常。

throw new FileNotFoundException(); 

所以沒有條件,你的程序執行總是在那里結束。

在以下 -

FileOutputStream fo = new FileOutputStream(f);

構造函數FileOutputStream(File)並不總是拋出該異常。

public FileOutputStream(File file) throws FileNotFoundException的throws子句public FileOutputStream(File file) throws FileNotFoundException只是說它可能拋出該異常,並且只有在運行時才會找到該文件,否則它將不會。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.6

如果實例初始值設定項無法正常完成,則為編譯時錯誤

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

非空交換塊的非空塊可以正常完成,如果其中的最后一個語句可以正常完成。

...

if語句,無論是否有else部分,都以不尋常的方式處理。 因此,本節末尾將單獨討論。

...

為了允許if語句方便地用於“條件編譯”目的,實際規則不同。

...

在第一種情況下,編譯器已經知道實例初始化器永遠不會正常完成,因為你已經在那里顯式拋出了FileNotFoundException 您可以說它是編譯器的智能代碼評估。 但是如果你讓編譯器相信實例初始化器甚至有一點成功完成的機會那么編譯器就不會在編譯時抱怨。 例如,在下面給出的代碼中雖然文件IDonotexist.txt在我的目錄中不存在,但我確信它會拋出FileNotFoundException但仍然編譯器會讓它成功編譯。 為什么? 因為在執行代碼期間檢查文件是否存在,而不是在編譯時檢查。

class A
{
    {
        FileReader fr = new FileReader(new File("IDonotexist.txt"));
    }
    public A() throws IOException
    {
        // TODO Auto-generated constructor stub
    }
    public static void main(String st[])throws Exception
    {
        A a = new A();
    }
}

這類似於最終變量初始化的情況。 對於以下代碼中的示例,編譯器將顯示編譯時錯誤

public void calling()
    {
        final int i;
        int k = 90;
        if ( k == 90)
        {
            i = 56;
        }
        System.out.println(i);//Compiler will show error here as: variable i might not have been initialized
    }

但是如果我用if(true)替換條件if ( k == 90) if(true)那么編譯器將不會顯示錯誤。 因為編譯器現在知道i肯定會被分配一些值。

暫無
暫無

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

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