您可以在此处比较从 AnimalHandler 在 Scala 和 Java 中生成的字节码:https://www.diffchecker.com/HyAuDYo5
Scala 中的class AnimalHandler[A <: Animal, F <: Food] 在 Java 中将被视为 class AnimalHanlder<A extends Animal, F extends Food>,反之亦然。
A <: B 表示A 是B 的子类型。在 Java 中创建子类型的唯一方法是继承
class Cow extends Animal
class Grasp extends Food
new AnimalHandler[Cow, Grasp]
(这就是为什么使用关键字 extends 而不是 <:)但是在 Scala 中有很多方法可以创建子类型:
val cow: Cow = new Cow
val grasp: Grasp = new Grasp
new AnimalHandler[cow.type, grasp.type]
或
type Cow <: Animal
type Grasp <: Food
new AnimalHandler[Cow, Grasp]
或
trait CowLike
trait GraspLike
new AnimalHandler[Animal with CowLike, Food with GraspLike]
或
trait Animal {
type F <: Food
}
trait Food
class Grasp extends Food
class Cow extends Animal {
override type F <: Grasp
}
new AnimalHandler[Cow, Cow#F]
或
val cow: Cow = new Cow
new AnimalHandler[cow.type, cow.F]
或
trait Animal
class Cow extends Animal
trait Food
class Grasp extends Food
trait GetFoodTypeclass[A <: Animal] {
type F <: Food
}
object GetFoodTypeclass {
implicit val cowGrasp: GetFoodTypeclass[Cow] { type F = Grasp } = null
}
def foo[A <: Animal](implicit getFood: GetFoodTypeclass[A]) = {
new AnimalHandler[A, getFood.F]
}
因此,Scala 的类型系统比 Java 的类型系统更强大,这就是子类型 (<:) 比子类 (extends) 更强大的原因。
在 Scala 中你也可以有下限
trait Animal
trait Mammal extends Animal
class Cow extends Mammal
class CowHandler[A >: Cow <: Animal]
new CowHandler[Mammal]
但在 Java 中,下限只能与通配符一起使用
interface Animal {}
interface Mammal extends Animal {}
class AnimalHanlder<A extends Animal> {}
void handle(AnimalHanlder<? super Mammal> handler) {}
在 Scala 中你也可以指定方差。