Scala之case class

我们在模式匹配中可以见到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()方法。

copy()方法,快速复制自己,并可以做少量变化
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,李程))

实现Product和Serializable接口

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";
    }
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zerlinda_Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值