2016-11-20 46 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',这是一个检查的异常的方法。 –