2013-05-02 88 views
3
private static int testReturn(final boolean flag) { 
    return flag ? 1 : 2; 
} 

private static void testThrow1(final boolean flag) 
    throws IOException, SQLException { 

    if (flag) { 
     throw new IOException("IO"); 
    } else { 
     throw new SQLException("SQL"); 
    } 
} 

當我試圖用?:操作去改變它,Java條件操作例外

private static void testThrow2(final boolean flag) 
    throws 
     //IOException, SQLException, // not even required 
     Exception {     // compiler wants this. 

    throw flag ? new IOException("IO") : new SQLException("SQL"); 
} 

它是正常的嗎?

謝意

當我正準備介紹了Java 7種的功能,如多副漁獲物和類型rethrowal我居然遇到了這個代碼。有趣。謝謝大家這些好的答案。我學到了很多。

更新

Java 7中已經爲特定類型重新引發了改進,對不對?

void throwIoOrSql() throws IOException, SQLException { 
} 

void rethrowIoAndSql() throws IOException, SQLException { 
    try { 
     throwIoOrSql(); 
    } catch (Exception e) { 
     throw e; // Ok with Java 7 
    } 
} 

這是有點愚蠢的編譯器無法看到這些明顯的情況。

throw flag ? new IOException("io") : new SQLException("sql"); // obvious, isn't it? 

回答

10

是的,不幸的是,編譯器無法弄清楚你可以拋出這兩個異常中的一個(並且語言規範不要求它)。

這裏有一個三元運算符,返回一個Exception。這可以是SQLExceptionIOException,但唯一的常見超類型是Exception,所以這就是編譯器將在此處看到的內容。

Java中沒有「聯合類型」。

同在這種情況下:

Object x = flag ? Integer.valueOf(1) : "a string"; 

這裏,x也將是一個Object,因爲沒有其他的類型來表達Integer || String

0

這是完全正常的,?:運營商做同樣的事情任何boolean值。

0

你的synatx是無效的。你可以做一些這樣的事情。

Exception ex = true ? new IOException(): new Exception(); 
throw ex; 
-1

b ? new E1() : new E2() 

reference conditional expression。 Java語言規範有關如何確定此表達式的類型的規則。你表達的規則是這樣的:

  • 否則,第二個和第三個操作數分別爲類型S1S2。假設T1是應用裝箱 轉換爲S1的結果,並且讓T2成爲將 裝箱轉換爲S2的結果。條件表達式的類型是應用捕獲轉換(§5.1.10)至lub(T1, T2)的 結果。

lubleast upper bound,在這種情況下,它解析爲Exception。由於Exception沒有catch塊,因此編譯器會抱怨。


編譯器抱怨

未處理的異常類型Exception

因爲lubIOExceptionSQLException(即該三元表達的類型)是Exception。編譯器本質上看,例如

private static void testThrow2(final boolean flag) throws IOException, SQLException { 
                // this won't compile 
    throw (Exception) new IOException("IO"); 
}