You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中如何实现Java风格的协变、逆变泛型约束列表

Scala中对应Java泛型通配符的等效写法

嘿,刚好我之前也纠结过这个问题,现在给你梳理清楚Scala里怎么写出和Java那两行代码等效的实现!

首先得明确Scala和Java泛型的一个核心区别:Scala的很多集合(比如不可变List)本身就声明了协变(List[+A]),这意味着如果Siamois是Chat的子类,那么List[Siamois]自动就是List[Chat]的子类型——这和Java不一样,Java里List[Siamois]不能直接赋值给List[Chat],必须用? extends来放宽类型约束。

不过如果你想要完全对应Java里的通配符写法(不管集合本身的协变性),或者处理可变集合的场景,写法如下:

对应Java的List<? extends Chat> chats = new ArrayList<Siamois>();

在Scala里,你可以用上界通配符_ <: Chat来实现,代码如下:

// 不可变List的写法
val chats: List[_ <: Chat] = List[Siamois]()

// 如果是可变集合(比如ListBuffer),写法类似
import scala.collection.mutable.ListBuffer
val mutableChats: ListBuffer[_ <: Chat] = ListBuffer[Siamois]()

当然,因为Scala的不可变List是协变的,你其实也可以直接写val chats: List[Chat] = List[Siamois](),这和上面的通配符写法效果一致,而且更简洁——这是Scala协变带来的便利。

对应Java的List<? super Siamois> siamois2 = new ArrayList<Chat>();

这里需要用下界通配符_ >: Siamois,对应Java的? super,代码示例:

// 不可变List的写法
val siamois2: List[_ >: Siamois] = List[Chat]()

// 可变集合的写法
val mutableSiamois2: ListBuffer[_ >: Siamois] = ListBuffer[Chat]()

这种写法的场景通常是你需要往集合里添加Siamois或其子类型的元素,就像Java里? super允许你写入子类型元素一样。

最后再总结一下:

  • Scala的_ <: A ≈ Java的? extends A(上界通配符,更适合读取操作)
  • Scala的_ >: A ≈ Java的? super A(下界通配符,更适合写入操作)

内容的提问来源于stack exchange,提问作者David Tavan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:33:56