本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

Java泛型:如何将一个泛型参数声明为另一个泛型参数的基类型?

发布于2023-09-25 20:22     阅读(1090)     评论(0)     点赞(8)     收藏(3)


public class PairJ<T> {
    private T first;
    private T second;

    public PairJ(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T first() {
        return this.first;
    }

    public T second() {
        return this.second;
    }

    public <R> Pair<R> replaceFirst(R newFirst) {
        return new Pair(newFirst, second());
    }
}

class Vehicle {}

class Car extends Vehicle {}

class Tank extends Vehicle {}

代码编译。但是当我这样做时:

    PairJ<Car> twoCars = new PairJ(new Car(), new Car());
    Tank actuallyACar = twoCars.replaceFirst(new Tank()).second();

它仍然可以编译,但在运行时会给出强制转换异常,因为该对中的第二个元素是汽车,而不是坦克。

所以我把它改成这样:

public <R, T extends R> Pair<R> replaceFirst(R newFirst) {
    return new Pair(newFirst, second());
}

但这段代码仍然可以编译并给出相同的异常:

    PairJ<Car> twoCars = new PairJ(new Car(), new Car());
    Tank actuallyACar = twoCars.replaceFirst(new Tank()).second();

似乎 T extends R 的声明在这里不起作用。

我如何在这里强制类型安全?

更具体地说,我如何确保 java 推断

twoCars.replaceFirst(new Tank())

退回一对车辆而不是一对坦克?因此,当我尝试将其第二个元素分配给 Tank 类型的变量时,会出现编译时错误?并减少出现运行时异常的机会?

编辑:

在Scala中,我们可以这样做:

class Pair[T](val first: T, val second: T) {
  def replaceFirst[R >: T](newFirst: R): Pair[R] = new Pair[R](newFirst, second)
}

[R >: T] 确保 R 是 T 的基类型,我们如何在 Java 中做同样的事情?


解决方案


我怎样才能确保java推断

twoCars.replaceFirst(new Tank())

退回一对车辆而不是一对坦克?

显式提供类型参数

twoCars.<Vehicle>replaceFirst(new Tank())

尝试调用时会出现编译器错误

Tank actuallyACar = twoCars.<Vehicle>replaceFirst(new Tank()).second();


所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:http://www.javaheidong.com/blog/article/677414/e6382263ed95e7840349/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

8 0
收藏该文
已收藏

评论内容:(最多支持255个字符)