加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 04:49:58 所属栏目:Java 来源:网络整理
导读:我遵循这段代码: 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.c
我遵循这段代码:

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);
    }
}

这里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线程的答案中提到的那样:How do I make the method return type generic?,允许使用T进行转换,并在此线程中给出另一个指针:Java Generics: Generic type defined as return type only.但我的问题是:当T有界且所有返回的对象都掉落时,为什么我需要使用类型转换进入指定的界限?

解决方法

你在做什么是错的.这就是你得到错误的原因.您可以使用ExceptionC exceptionC = managedException(ExceptionD d)调用您的方法,最终会得到一个强制转换(ExceptionC)异常D;并且它会掩盖错误但你在运行时得到它.

将您的方法更改为:

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);
    }
}

你这里不需要泛型.所有这些异常也是ParentExceptions,因此您可以返回它们.当你考虑它时,你试图让方法返回不同的类型.这样做是不可能的,因为如果你有一个从这个方法初始化的变量,你需要知道结果是什么.而且您知道结果将是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)新的B();这是不兼容的,但我们已经屏蔽它,我们在运行时获得异常

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读