Java 中使用 <> 符号来包含定义的类型参数,Scala 则使用 []。
class Pair[T, S](val first: T, val second: S) { override def toString: String = first + ":" + second } object ScalaApp extends App { // 使用时候你直接指定参数类型,也可以不指定,由程序自动推断 val pair01 = new Pair("heibai01", 22) val pair02 = new Pair[String,Int]("heibai02", 33) println(pair01) println(pair02) } 1.2 泛型方法函数和方法也支持类型参数。
object Utils { def getHalf[T](a: Array[T]): Int = a.length / 2 } 二、类型限定 2.1 类型上界限定Scala 和 Java 一样,对于对象之间进行大小比较,要求被比较的对象实现 java.lang.Comparable 接口。所以如果想对泛型进行比较,需要限定类型上界为 java.lang.Comparable,语法为 S <: T,代表类型 S 是类型 T 的子类或其本身。示例如下:
// 使用 <: 符号,限定 T 必须是 Comparable[T]的子类型 class Pair[T <: Comparable[T]](val first: T, val second: T) { // 返回较小的值 def smaller: T = if (first.compareTo(second) < 0) first else second } // 测试代码 val pair = new Pair("abc", "abcd") println(pair.smaller) // 输出 abc扩展:如果你想要在 Java 中实现类型变量限定,需要使用关键字 extends 来实现,等价的 Java 代码如下:
public class Pair<T extends Comparable<T>> { private T first; private T second; Pair(T first, T second) { this.first = first; this.second = second; } public T smaller() { return first.compareTo(second) < 0 ? first : second; } } 2.2 视图界定在上面的例子中,如果你使用 Int 类型或者 Double 等类型进行测试,点击运行后,你会发现程序根本无法通过编译:
val pair1 = new Pair(10, 12) val pair2 = new Pair(10.0, 12.0)之所以出现这样的问题,是因为 Scala 中的 Int 类并没有实现 Comparable 接口。在 Scala 中直接继承 Comparable 接口的是特质 Ordered,它在继承 compareTo 方法的基础上,额外定义了关系符方法,源码如下:
// 除了 compareTo 方法外,还提供了额外的关系符方法 trait Ordered[A] extends Any with java.lang.Comparable[A] { def compare(that: A): Int def < (that: A): Boolean = (this compare that) < 0 def > (that: A): Boolean = (this compare that) > 0 def <= (that: A): Boolean = (this compare that) <= 0 def >= (that: A): Boolean = (this compare that) >= 0 def compareTo(that: A): Int = compare(that) }之所以在日常的编程中之所以你能够执行 3>2 这样的判断操作,是因为程序执行了定义在 Predef 中的隐式转换方法 intWrapper(x: Int),将 Int 类型转换为 RichInt 类型,而 RichInt 间接混入了 Ordered 特质,所以能够进行比较。
// Predef.scala @inline implicit def intWrapper(x: Int) = new runtime.RichInt(x)