2016-11-20 81 views
0

我有兩種方法:Java泛型與異常產生編譯時錯誤

private static <T extends Throwable> void methodWithExceptionGeneric(final T t) throws T { 
    throw t; 
} 

private static void methodWithExceptionNonGeneric(final Throwable t) throws Throwable { 
    throw t; 
} 

當我調用這些方法如下所示:

methodWithExceptionGeneric(new IllegalArgumentException()); 
methodWithExceptionNonGeneric(new IllegalArgumentException()); // compile time error 

我得到的非泛型方法編譯時錯誤說我的主方法中有一個未處理的異常,我需要聲明一個throws語句或捕獲異常。

我的問題是:爲什麼它只是抱怨非泛型方法?在我看來,泛型方法也拋出異常,所以不應該被處理呢?

+0

你知道關於檢查和未檢查的異常嗎?什麼樣的'IllegalArgumentException'? –

+0

@SotiriosDelimanolis我不知道 – Ogen

+0

@Ogen然後谷歌,檢查文檔:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html,看到它擴展了一個'java.lang.RuntimeException' – alfasin

回答

1

原因很簡單:
IllegalArgumentExceptionRuntimeException,這意味着它是一個未經檢查的例外。你可以抓住它,但你不需要。由於通用方法只通過它的規範拋出IllegalArgumentException,所以編譯器不會抱怨(未經檢查的異常)。

的方法,而不會對另一方面泛型被指定爲引發任何Throwable,這意味着它也可以拋出未經檢查的異常(和錯誤),其需要被處理。

這得到不難看出,一旦你嘗試理解與泛型方法會發生什麼:

methodWithExceptionGeneric(new IllegalArgumentException()); 

相當於

methodWithExceptionGeneric<IllegalArgumentException>(new IllegalArgumentException()); 

當我們來看看定義

private static <T extends Throwable> void methodWithExceptionGeneric(final T t) throws T ... 

變成

private static <IllegalArgumentException> void methodWithExceptionGeneric(IllegalArgumentException) throws IllegalArgumentException ... 

所以methodWithExceptionGeneric(new IllegalArgumentException());每個定義只能拋出IllegalArgumentException或任何其他未檢查的Exception。另一方面,非泛型方法可以拋出任何Exception,無論是選中還是取消選中,因此必須在try-catch - 塊處理該方法拋出的任何內容時調用。

+0

所以我會如何需要更改非泛型方法以使編譯時錯誤消失?我將參數類型更改爲'RuntimeException',以便它是一個未經檢查的異常,據說我不必捕捉它,但編譯器仍在抱怨。 – Ogen

+1

@Ogen這是抱怨,因爲你扔't'這是一個'Throwable',這是一個檢查的異常的方法。 –