我们在模式匹配中可以见到case

a match {
    case b => ...
    case _ => ...
}

我们在类定义时,有时也会见到case关键字

case class Person (age: Int, name: String)

那么,在类上加上case关键字意味着什么呢?

伴生对象

编译Person.scala会产生两个class, Person.class和Person$class. 编译器给scala自动添加了一个伴生对象object Person

apply()方法和unapply()方法

伴生对象Person里面实现了apply()方法如下,

public Person apply(int age, String name){
    return new Person(age, name);
}

所以我们创建一个实例的时候不需要使用关键字new,可以直接通过Person(age,name)来得到一个实例对象

伴生对象Person里面还实现了unapply()方法,将对象转为可选元组集合Option[Tuple]

    public scala.Option<scala.Tuple2<Object, Object>> unapply(Person person) {
        if (person == null) {
            return scala.None$.MODULE$;
        }
        return new scala.Some(new scala.Tuple2$mcll$sp(person.age, person.name))

我们来看看代码

object CaseClassDriver {
  def main(args: Array[String]): Unit = {
    val p = Person(13,"李程")
    println(p.toString)

    val p$ = Person.unapply(p)
    println(p$.toString)
  }
}

/**
  * case class 编译后会生成两个class文件Person.class和Person$.class
  * Person$.class是伴生对象,实现了apply方法和unapply方法
  * apply方法返回一个实例对象
  * unapply方法将对象转为元组
  */
case class Person(age: Int, name: String)

Case Class默认是Immutable

case类的字段会被编译器默认加上val关键字。 所以Person.class中的age和name都被定义成了final, 且伴生对象Person$.class的定义也是

public final class Person$ {
    ...
}

toString()、hashCode()和equals()方法

Scala编译器负责(根据字段)给Case类重写toString()、hashCode()和equals()方法。