Java 泛型:返回有界泛型类型

2024-03-23

我有以下代码:

public <T extends ParentException> T managedException(Exception cause) {        
    if(ExceptionA.class.isInstance(cause)) {
        return ExceptionA.class.cast(cause);
    } else if(ExceptionB.class.isInstance(cause)) {
        return ExceptionB.class.cast(cause);
    } else if(ExceptionC.class.isInstance(cause)){
        return ExceptionC.class.cast(cause);
    } else {
        return new ExceptionD(cause.getMessage(), cause);
    }
}

Here ExceptionA, ExceptionB, ExceptionC, ExceptionD是的孩子ParentException.

编译时,我收到错误:

incompatible types: ExceptionA cannot be converted to T
incompatible types: ExceptionB cannot be converted to T
incompatible types: ExceptionC cannot be converted to T
incompatible types: ExceptionD cannot be converted to T

但是,如果我将代码更改为:

@SuppressWarnings("unchecked")
public <T extends ParentException> T managedException(Exception cause) {        
    if(ExceptionA.class.isInstance(cause)) {
        return (T) ExceptionA.class.cast(cause);
    } else if(ExceptionB.class.isInstance(cause)) {
        return (T) ExceptionB.class.cast(cause);
    } else if(ExceptionC.class.isInstance(cause)){
        return (T) ExceptionC.class.cast(cause);
    } else {
        return (T) new ExceptionD(cause.getMessage(), cause);
    }
}

它可以正常工作,没有编译错误。

正如SO线程的这个答案中提到的:如何使方法返回类型通用? https://stackoverflow.com/a/450852/576758, 铸造T是允许的,并且在此线程中给出了另一个指针:Java 泛型:泛型类型仅定义为返回类型 https://stackoverflow.com/q/338887/576758。但我的问题是:为什么我需要使用类型转换T是有界的并且所有返回的对象都落入指定的范围内?


你所做的事情是错误的。这就是您收到错误的原因。您可以使用以下方式调用您的方法ExceptionC exceptionC=managedException(ExceptionD d)你最终会得到一个演员阵容(ExceptionC) exceptionD;转换它会掩盖错误,但你会在运行时得到它。

将您的方法更改为:

public ParentException managedException(Exception cause) {        
    if(ExceptionA.class.isInstance(cause)) {
        return ExceptionA.class.cast(cause);
    } else if(ExceptionB.class.isInstance(cause)) {
        return ExceptionB.class.cast(cause);
    } else if(ExceptionC.class.isInstance(cause)){
        return ExceptionC.class.cast(cause);
    } else {
        return new ExceptionD(cause.getMessage(), cause);
    }
}

这里不需要泛型。所有这些异常也是 ParentException,因此您可以直接返回它们。当您考虑它时,您正在尝试使该方法返回不同的类型。不能这样做,因为如果您有一个从此方法初始化的变量,您需要知道结果是什么。并且您知道结果将是 ParentException,但您无法知道那是哪种父异常。

其背后的原因是,如果您的方法写成这样,则不会返回 ParentException - 它会返回 T (子类)。您可以返回一种不同类型的子类,而不是您想要获取的子类。

在一个更简单的例子中,如果我们有:

class A {}

class B extends A{  };

class C extends A{  };

public  <T extends A> T test() {        
        return (T) new B();
}   

我们可以用C c=test();我们实际上尝试投射(C) new B();这是不兼容的,但我们已经屏蔽了它,并且我们在运行时得到了异常

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 泛型:返回有界泛型类型 的相关文章

随机推荐