scala 的类层级如下图:

scala 类层级图

在 Any 当中包含了如下方法:

1
2
3
4
5
final def ==(that: Any): Boolean
final def !=(that: Any): Boolean
def equals(that: Any): Boolean
def hashCode: Int
def toString: String

Any 有两个子类:AnyVal 和 AnyRef。

AnyVal 是 scala 当中内建值类的父类:Byte,Short,Char,Int,Long,Float,Double,Boolean 和 Unit。Unit 大约对应于 Java 的 void 类型,被用作不返回任何有趣结果的方法的结果类 型。Unit 只有一个实例值,被写作()。

AnyRef 实际就是类 java.lang.Object 的别名。

原始类型

在 scala 当中的整数需要被当作(Java)对象看待的时候,Scala 使用了“备份”类java.lang.Integer。

看下面一个在 scala 当中与 java 不同的例子:

1
2
3
4
5
6
7
8
scala>def isEqual(x:Int, y:Int) = x == y
isEqual:(Int,Int)Boolean
scala>isEqual(421,421)
res10:Boolean = true
scala>def isEqual(x:Any, y:Any) = x == y
isEqual:(Any,Any)Boolean
scala>isEqual(421,421)
res11:Boolean = true

实际上 Scala 里的相等操作 == 被设计为透明的参考类型代表的东西。对值类型来说,就是自然的 (数学或布尔)相等。对于引用类型, == 被视为继承自 Object 的 equals 方法的别名。在 Scala 里你永远也不会落入 Java 知名的关于字串比较的陷阱。

1
2
3
4
5
6
scala>val x = "abcd".substring(2)
x:java.lang.String = cd
scala>val y = "abcd".substring(2)
y:java.lang.String=cd
scala>x==y
res12:Boolean=true

有些时候我们需要比较两个对象的引用是否相等,可以使用 AnyRef 附加的 eq 方法,它不能被重载并且实现为引用相等。同样也有一个 eq 的反义词,被称为 ne。

1
2
3
4
5
6
7
8
9
10
scala>val x = new String("abc")
x:java.lang.String = abc
scala>val y = new String("abc")
y:java.lang.String = abc
scala>x == y
res13:Boolean = true
scala>x eq y
res14:Boolean = false
scala>x ne y
res15:Boolean = true

底层类型

在上面的图的最下面有两个类 scala.Null 和 Scala.Nothing。它们是用统一的方式处理某些 Scala 的面向对象类型系统的“边界情况”的特殊类型。

类 Null 是 null 类型的引用;它是每个继承自 AnyRef 的类的子类。Null 不兼容值类型,即不能把 null 值赋给整数变量。

类型 Nothing 在 Scala 的类层级的最底端;它是任何其它类型的子类型。然而,根􏰁没有这个类 型的任何值。

Nothing 的一个用处是用来标识不正常的终止。例如:

1
def error(message:String): Nothing = throw new RuntimeException(message)

error 的返回类型是 Nothing,告诉用户方法不是正常返回的(代之以抛出了异常)。

因为 Nothing 是任何类型的子类型,所以我们可以这样使用它。

1
2
3
def divide(x:Int, y:Int): Int =
if(y != 0) x / y
else error("can't divide by zero")

当 y 为 0 的时候认为是异常情况。

【参考资料】

  1. Scala编程

—EOF—