我们在模式匹配中可以见到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
伴生对象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类的字段会被编译器默认加上val关键字。
所以Person.class中的age和name都被定义成了final, 且伴生对象Person$.class的定义也是
public final class Person$ {
...
}
Scala编译器负责(根据字段)给Case类重写toString()、hashCode()和equals()方法。
package base.day05.caseobject
/**
* @description CaseObjDriver
* @author ZerlindaLi create at 2019/4/29 20:32
* @version 1.0.0
*/
object CaseClassDriver {
def main(args: Array[String]): Unit = {
val p = Person(13,"李程")
val p2 = p.copy()
val p22 = Person(13,"李程")
val p3 = p.copy(age=14)
println(p.toString + p2.toString + p3.toString)
println(p.hashCode)
println("p.equals(p):"+p.equals(p))
println("p.equals(p22):"+p.equals(p22))
println("p.equals(p2):"+p.equals(p2))
println("p2.equals(p3):"+p2.equals(p3))
val p$ = Person.unapply(p)
println(p$.toString)
}
}
/**
* case class 编译后会生成两个class文件Person.class和Person$.class 默认为Immutable
* Person$.class是伴生对象,实现了apply方法和unapply方法
* apply方法返回一个实例对象
* unapply方法将对象转为元组
* 重写了toString,equals,hashCode方法
*/
case class Person(age: Int, name: String)
运行结果为
Person(13,李程)Person(13,李程)Person(14,李程)
-89502882
p.equals(p):true
p.equals(p22):true
p.equals(p2):true
p2.equals(p3):false
Some((13,李程))
Case类还实现了scala.Product和scala.Serializable接口(Product和Serializable实际上都是Traits)。
// Product
// def productArity: Int
// def productElement(n: Int): Any
// def productIterator: Iterator[Any]
// def productPrefix = ""
public int productArity() {
return 2;
}
public Object productElement(int n) {
switch (n) {
case 0: return age();
case 1: return name();
default: throw new IndexOutOfBoundsException();
}
}
public scala.collection.Iterator productIterator() {
return scala.runtime.ScalaRunTime$.MODULE$.typedProductIterator(this);
}
public String productPrefix() {
return "Person";
}