结论
case class又称样例类,可用于DTO(序列化特性),模式匹配(unapply特性).
作为一种语法糖,在定义之后会隐式获得很多经典的方法.
1. case class与case object
无参数时,使用case object;
有参数时,使用case class.case object比参数为()的case class少apply和unapply方法.
2. 类参数
类参数默认作为private final的类成员.
同时自动生成一个同名public方法以获取它的值.
3. 伴生对象
- apply方法和- unapply方法:- case class会自动生成一个伴生对象(- object),作为当前作用域的一个单例,同时在里面实现了- apply方法,可以使用- apply方法或者括号函数- ()创建对象.(也可以依旧使用- new关键字)
 由于有- unapply方法实现,因此可以用于模式匹配.
4. 序列化特性
详情
1. 用IDE查看class文件
假如写这么一个scala文件:
| 1 | package learn | 
编译后生成的class文件会有两个:
| 1 | TestCaseClass$.class | 
用IDE打开TestCaseClass.class是:
| 1 | package learn | 
可见定义case class后,自动会继承AnyRef,加上Product和Serializable的trait.
另一个内部类文件TestCaseClass$.class虽然用ide打开为空,但看文件大小1180,可见并不是空文件.
2. 反编译
使用javap -p -c -s TestCaseClass.class查看,过滤掉看不懂的部分和常量池里的各种符号引用,大致能发现如下内容:
- 类签名 - 1 - public class learn.TestCaseClass implements scala.Product,scala.Serializable - 可见本质上是实现Product和Serializable的接口.(加上默认实现) 
- 方法: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- public static boolean unapply(learn.TestCaseClass); 
 public static learn.TestCaseClass apply();
 public learn.TestCaseClass copy();
 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 learn.TestCaseClass();- 注意到 - unapply和- apply方法是- static的,说明会自动生成一个伴生对象,并添加这两个方法.(- static方法在- object里)
反编译内部类:
- 类签名:可见1 public final class learn.TestCaseClass$ extends scala.runtime.AbstractFunction0<learn.TestCaseClass> implements scala.Serializable case class其实也是作为一个Function存在的,如果把源码改动一下加上参数:1 
 2package learn 
 case class TestCaseClass(xyz:String)
则这里的类签名变为:
| 1 | public final class learn.TestCaseClass$ extends scala.runtime.AbstractFunction1<java.lang.String, learn.TestCaseClass> implements scala.Serializable | 
此外由于类参数没有加限定,默认变成了val,因此类参数是private final的:
| 1 | private final java.lang.String xyz | 
其中AbstractFuction是一个抽象类,源码为:
| 1 | abstract class AbstractFunction0[@specialized(Specializable.Primitives) +R] extends Function0[R] {} | 
- 方法签名:1 
 2
 3
 4
 5public static {};// 3: invokespecial #15 // Method "<init>":()V 
 public final java.lang.String toString();
 public learn.TestCaseClass apply();
 public boolean unapply(learn.TestCaseClass);
 public java.lang.Object apply();
