参数的类无法编译-6ren"> 参数的类无法编译-我不明白为什么 classB 无法编译: interface Interface { void method(List list) throws T; } // It compile but th-6ren">
gpt4 book ai didi

java - 在异常 "throws"中使用泛型并具有 List 参数的类无法编译

转载 作者:行者123 更新时间:2023-12-01 18:05:03 24 4
gpt4 key购买 nike

我不明白为什么 classB 无法编译:

interface Interface {
<T extends Exception>void method(List<String> list) throws T;
}

// It compile but there is a warning (I understand why)
class ClassA implements Interface {
public void method(List list) throws Exception{}
}

// This class don't compile (I don't get why)
class ClassB implements Interface {
public void method(List<String> list) throws Exception{}
}

ClassB 中的编译器错误消息:

The method method_1(List) of type ClassB has the same erasure as method_1(List) of type Interface but does not override it

或者也许问题是为什么 ClassA 可以编译。

为什么 会产生差异?

最佳答案

让我们先介绍一下ClassB

方法的类型参数由方法的调用者解析。它无法通过子类中的重写来解决。

有两种方法可以使ClassB工作。您也可以在此处添加类型参数。1

class ClassB implements Interface {
public <T extends Exception> void method(List<String> list) throws T{}
}

或者您可以将类型参数移至接口(interface),以便子类可以决定。

interface Interface<T extends Exception> {
void method(List<String> list) throws T;
}
class ClassB implements Interface<Exception> {
public void method(List<String> list) throws Exception {}
}
<小时/>

至于为什么ClassA有效,是因为参数中的原始类型。当您使用原始类型时,一切都变成原始类型,这意味着在编译ClassA时,Interface看起来像这个原始类型。

interface Interface {
void method(List list) throws Exception;
}

这样做是为了向后兼容。请参阅JLS 4.8 Raw Types :

The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of its parameterized invocations.

它接着说:

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.

<小时/>

1 我实际上想知道调用者如何解析T,即编译器如何推断T > 是,假设方法调用中没有任何内容表明有效的异常。

根据 Eclipse 编译器,当您编写以下内容时,T 将被解析为 RuntimeException

new ClassB().method(null);

您可以通过显式给出类型来覆盖它,例如这将使该方法抛出 ParseException

new ClassB().<ParseException>method(null);

后续

在 Java 8 中,推断的 TRuntimeException。如果没有 catch 语句,我在早期版本的 Java 上会收到以下错误:

1.5.0_22: unreported exception T; must be caught or declared to be thrown
1.6.0_45: unreported exception T; must be caught or declared to be thrown
1.7.0_79: error: unreported exception Exception; must be caught or declared to be thrown

Java 8 专门用了一整章来介绍 type inference ,它说:

if the bound set contains throws αi, and the proper upper bounds of αi are, at most, Exception, Throwable, and Object, then Ti = RuntimeException.

关于java - 在异常 "throws"中使用泛型并具有 List<String> 参数的类无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37121312/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com