概述:

case类在模式匹配和actor中经常使用到,当一个类被定义成为case类后,Scala会自动帮你创建一个伴生对象并帮你实现了一系列方法且带来了不少好处,如下:

1.实现了apply方法,意味着你不需要使用new关键字就能创建该类对象
scala> case class People(name:String,age:Int)
defined class People scala> val p = People("mobin",22) //省略了new关键字
p: People = People(mobin,22)

  

2.实现了unapply方法,可以通过模式匹配来获取类属性,是Scala中抽取器的实现和模式匹配的关键方法。
scala> p match { case People(x,y) => println(x,y) }
(mobin,22)

 

3.实现了类构造参数的getter方法(构造参数默认被声明为val),但是当你构造参数是声明为var类型的,它将帮你实现setter和getter方法(不建议将构造参数声明为var)

 
构造参数为val的情况(默认):
scala> p.name
res0: String = mobin scala> p.name = "mobin1" //报错,因为构造参数被声明为val所以并没有帮你实现setter方法
<console>:10: error: reassignment to val
p.name = "mobin1"
 
构造参数为var的情况:
scala> case class People(var name:String) //参数被声明为var
defined class People scala> val p = People("mobin")
p: People = People(mobin) scala> p.name = "mobin2"
p.name: String = mobin2 scala> p.name
res1: String = mobin2 //修改成功,并没有报错

  

4.还默认帮你实现了toString,equals,copy和hashCode等方法
 
详述:
我们再通过反编译来看看当你定义一个case类时编译器是怎么做的:
同样定义一个简单的case类:
Person.scala
case class Person(name: String,age : Int)

  

通过终端中编译该文件(scalac Person.scala)后生成两个class文件,Person.class和Person$.class
 
接下来再通过javap Person命令反编译Person.class,结果结果如下:
Compiled from "Person.scala"
public class com.mobin.scala.Person implements scala.Product,scala.Serializable {
public static scala.Function1<scala.Tuple2<java.lang.String, java.lang.Object>, com.mobin.scala.Person> tupled();
public static scala.Function1<java.lang.String, scala.Function1<java.lang.Object, com.mobin.scala.Person>> curried();
public java.lang.String name();
public int age();
public com.mobin.scala.Person copy(java.lang.String, int);
public java.lang.String copy$default$1();
public int copy$default$2();
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public scala.collection.Iterator<java.lang.Object> productIterator();
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public com.mobin.scala.Person(java.lang.String, int);
}
 
再反编译Person$.class
Compiled from "Person.scala"
public final class com.mobin.scala.Person$ extends scala.runtime.AbstractFunction2<java.lang.String, java.lang.Object, com.mobin.scala.Person> implements scala.Serializable {
public static final com.mobin.scala.Person$ MODULE$;
public static {};
public final java.lang.String toString();
public com.mobin.scala.Person apply(java.lang.String, int);
public scala.Option<scala.Tuple2<java.lang.String, java.lang.Object>> unapply(com.mobin.scala.Person);
public java.lang.Object apply(java.lang.Object, java.lang.Object);
}
 
通过反编译以上两个class文件可以知道,当你将一个类定义为case类后,编译器就自动帮你实现了一系列方法。
 
我们再来对比下去掉case关键字将类定义为普通类后反编译的结果
class Person(var name : String,var age : Int) //将参数声明为var

  

反编译的结果如下:
Compiled from "Person.scala"
public class com.mobin.scala.Person {
public java.lang.String name();
public void name_$eq(java.lang.String);
public int age();
public void age_$eq(int);
public com.mobin.scala.Person(java.lang.String, int);
}

  

比较之下case类比普通的类多了不少的方法,所以当你不需要这些额外的方法时你就可以将类定义为普通的类,但是你又不想通过new关键字来创建实例,你可以在普通类中实现apply方法达到此目的。
 
因为case本就旨在创建的是不可变数据,所以在使用模式匹配时显得极为容易
 

Scala--样例类(case)详解的更多相关文章

  1. WPF 后台任务 等待动画 样例 && C# BackgroundWorker 详解

    运行效果: 前台代码: <Window x :Class="Waiting.Window1" xmlns="http://schemas.microsoft.com ...

  2. 28.C++- 单例类模板(详解)

    单例类 描述 指在整个系统生命期中,一个类最多只能有一个实例(instance)存在,使得该实例的唯一性(实例是指一个对象指针)  , 比如:统计在线人数 在单例类里,又分为了懒汉式和饿汉式,它们的区 ...

  3. scala 样例类

    一.case class 的特征 package com.jason.qianfeng case class Message(sender: String, receiver: String, bod ...

  4. 【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型

    一.前述 Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大. 模式匹配机制相当于java中的switch-case. 使用了case关键字的类定义就是样例类(case ...

  5. Scala基础:模式匹配和样例类

    模式匹配 package com.zy.scala import scala.util.Random /** * 模式匹配 */ object CaseDemo { def main(args: Ar ...

  6. 学好Spark/Kafka必须要掌握的Scala技术点(二)类、单例/伴生对象、继承和trait,模式匹配、样例类(case class)

    3. 类.对象.继承和trait 3.1 类 3.1.1 类的定义 Scala中,可以在类中定义类.以在函数中定义函数.可以在类中定义object:可以在函数中定义类,类成员的缺省访问级别是:publ ...

  7. Scala模式匹配和样例类

    Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等.并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配. 1.字符匹配     def mai ...

  8. Scala学习十四——模式匹配和样例类

    一.本章要点 match表达式是更好的switch,不会有意外调入下一个分支 如果没有模式能够匹配,会抛出MatchError,可以用case _模式避免 模式可以包含一个随意定义的条件,称做守卫 你 ...

  9. Scala集合库、模式匹配和样例类

    package com.yz8 import org.junit.Test class test { @Test def test: Unit = { val ints = List(1,5,7,6, ...

随机推荐

  1. shadow projection

    1.概述 shadow projection,又可成为planar shadow, 这是一种非常简单的绘制阴影的方法. 主要应用的应用场景:物体在平面投射阴影. 主要思想:把阴影看作是物体在平面上的投 ...

  2. Android应用切换皮肤功能实现

    原文地址:http://www.eoeandroid.com/thread-318159-1-1.html 现在大多数android应用都支持切换皮肤的功能.比如千千静听,墨迹天气等等.本文介绍两种切 ...

  3. MySql命令——show,分页,正则表达式

    先要安装MySql,过程见 MySql5.1在Win7下的安装与重装问题的解决 不是教程,还没有写教程的资格,只是为了自己查阅而已!   show show databases; //显示所有数据库 ...

  4. 《JavaScript 闯关记》之垃圾回收和内存管理

    JavaScript 具有自动垃圾收集机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存.而在 C 和 C++ 之类的语言中,开发人员的一项基本 ...

  5. iOS-OC-基础-NSArray常用方法

    NSArray常用方法和属性 // ——————————————————————数组常用方法—————————————————————— // 1.计算数组元素的个数: count NSArray * ...

  6. 内存管理pbuf.h头文件源码解析——LwIP学习

    声明:个人所写所有博客均为自己在学习中的记录与感想,或为在学习中总结他人学习成果,但因本人才疏学浅,如果大家在阅读过程中发现错误,欢迎大家指正. LwIP的内核(core文件夹)文件中pbuf.c是包 ...

  7. c++ 指针的简单用法

    对于指针,其实只需要明白几点就可以. 1.指针,是一个数值为地址的变量,这里尤其注意,指针变量的值是地址!就是例如40002这种像门牌号的地址值,其实就是内存中的一个编号. 2.&,该符号的意 ...

  8. (转) 制作 Clonezilla live 启动盘

    GNU/Linux Method A: Tuxboot 下載 GNU/Linux 版本使用的 Tuxboot 在您的環境 在 GNU/Linux 下, 請依 指示 來執行 Tuxboot 並安裝再生龍 ...

  9. mysql 使用set names 解决乱码问题的原理

    解决乱码的方法,我们经常使用“set names utf8”,那么为什么加上这句代码就可以解决了呢?下面跟着我一起来深入set names utf8的内部执行原理 先说MySQL的字符集问题.Wind ...

  10. struts2 0day漏洞

    描述 Apache Struts2 近日出现一个0day漏洞,该漏洞在修补CVE-2014-0050和2014-0094两个安全漏洞处理不当,分别可以导致服务器受到拒绝服务攻击和被执行恶意代码. 漏洞 ...