Scala底层基类简述

 

scala类库文档

Scala中,最顶端的两个trait是Nothing和Null:

Nothing:

abstract final class Nothing extends Any

Nothing是其它任何类型的子类型(包括scala.Null)。Nothing类型没有实例。尽管Nothing类型没有实例,然而它在一些方面也是非常有用的。例如:

  1. Scala库scala.collection.immutable.Nil定义了一个List[Nothing]值类型,因为scala中的list是协变(关于协变不在这里详述)的。 这使得scala.collection.immutable.Nil的List[T],T可以是任意类型。
  2. Nothing可以作为一个方法的返回值类型,这个方法不能正常的返回。一个例子就是:scala.sys中的error方法,它总是抛出一个异常

 

Null: Null是任何引用类型的子类型,它唯一的实例就是null引用。由于Null不是数值类型的子类型,故null不是数值类型的成员。举例来说,就是不能将null赋值给一个scala.Int类型

abstract final class Null extends AnyRef

 

 

Any:Any类是个比较重要的类,其中定义了isInstanceOf和asInstanceOf等方法,以及equals、hashCode等对象的基本方法,Any类,有点像Java中的Object基类

abstract class Any

类Any是Scala类层次结构的根。Scala执行环境中的每一个类都直接或间接地从这个类继承。
从Scala 2.10开始,可以直接继承Any使用任何通用的特性(Any类中的方法,equals,asInstanceOf等)。一个普遍的特征,是一个trait继承Any后,只有defs这个成员,并且不需要初始化。通用特性的主要用例是允许对值类(value class)的方法进行基本继承。看下例:

trait Printable extends Any {
  def print(): Unit = println(this)
}
class Wrapper(val underlying: Int) extends AnyVal with Printable

val w = new Wrapper(3)
w.print()

 

 

AnyRef:AnyRef类,增加了一些多线程的方法,比如wait、notify/notifyAll、synchronized等,也是属于Java Object类的一部分

     Class AnyRef是所有引用类型的根类。除了值类型之外,所有类型都来自这个类。

class AnyRef extends Any

 


AnyVal:AnyVal是所有值类型的根类,它描述在底层主机系统中未实现的值。Value类是在Sc ala语言规范第12.2节中指定的。                                  

标准的实现包括9个AnyVal子类型:

  • 数值类型:scala.Double, scala.Float, scala.Long, scala.Int, scala.Char, scala.Short, and scala.Byte
  • 非数值类型:scala.Unit 和 scala.Boolean

其它一些分组方式:

  • 子串类型:scala.Byte, scala.Short, and scala.Char.
  • 整数类型:包括子串类型和scala.Int以及scala.Long.
  • 浮点类型:scala.Float和scala.Double.

在Scala 2.10之前,AnyVal是一个封闭的特性。但是呢,从Scala 2.10开始,可以定义AnyVal的子类,称为用户定义的超值类,它是由编译器专门处理的。适当定义的user value类提供了一种方法,通过在运行时避免对象分配,以及用静态方法调用替换虚拟方法调用,从而提高用户定义类型的性能。

用户自定义的值类,如何避免对象分配呢?

  1. 必须有一个val参数,这是底层运行时表示,就是没有这个底层不能识别为自定义值类,我理解。
  2. 可以定义defs,但不要vals、vars,或者嵌套traitss、class或者object。
  3. 一般来说,不要去继承其他trait,只有AnyVal。
  4. 不能用于类型测试或模式匹配。
  5. 不能覆盖equals或hashCode方法。

一个小实例,可以参考:

class Wrapper(val underlying: Int) extends AnyVal {
    def foo: Wrapper = new Wrapper(underlying * 19)
}

需要注意的是,用户定义的值类是有限制的,并且在某些情况下,仍然必须在运行时分配一个值类实例。这些限制和环境在价值类和通用特性中得到了更详细的解释,这里就不解释了,可以参考这里。

 

posted @ 2018-08-24 00:11  胜迹寻芳  阅读(297)  评论(0编辑  收藏  举报