简介
本文主要介绍case class
与普通class
的一些区别。以及case class
与case object
的异同点。
case class
与class
的区别
Person.scala
源码,运行后生成Person$.class
和Person.class
两个文件。
1
2
3
4
5
6
7
8 case class Person(age:Int, name:String)
object Person {
def main(args: Array[String]): Unit = {
val person = Person(25,"stm")
println(person.toString)
}
}
对
Person.class
反编译如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 import scala.Function1;
import scala.Option;
import scala.Product;
package com.stm.datastructures.caseClass;
class;
import scala.Serializable;
import scala.Tuple2;
import scala.collection.Iterator;
import scala.reflect.ScalaSignature;
import scala.runtime.BoxesRunTime;
import scala.runtime.ScalaRunTime.;
import scala.runtime.Statics;
public class Person
implements Product, Serializable {
private final int age;
private final String name;
public Person(int age, String name) {
Product.class.$init$(this);
}
public boolean equals(Object x$1) {
if (this != x$1) {
Object localObject = x$1;
int i;
if ((localObject instanceof Person)) {
i = 1;
} else {
i = 0;
}
if (i == 0) {
break label96;
}
Person localPerson = (Person) x$1;
if (age() == localPerson.age()) {
str = localPerson.name();
String tmp54_44 = name();
if (tmp54_44 == null) {
tmp54_44;
if (str == null) {
break label75;
}
tmpTernaryOp = tmp54_44;
break label88;
}
}
}
}
public String toString() {
return ScalaRunTime..MODULE$._toString(this);
}
public int hashCode() {
int i = -889275714;
i = Statics.mix(i, age());
i = Statics.mix(i, Statics.anyHash(name()));
return Statics.finalizeHash(i, 2);
}
public boolean canEqual(Object x$1) {
return x$1 instanceof Person;
}
public Iterator<Object> productIterator() {
return ScalaRunTime..MODULE$.typedProductIterator(this);
}
public Object productElement(int x$1) {
int i = x$1;
switch (i) {
default:
throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(x$1).toString());
case 1:
break;
}
return BoxesRunTime.boxToInteger(age());
}
public int productArity() {
return 2;
}
public String productPrefix() {
return "Person";
}
public String copy$default$2() {
return name();
}
public int copy$default$1() {
return age();
}
public Person copy(int age, String name) {
return new Person(age, name);
}
public String name() {
return this.name;
}
public int age() {
return this.age;
}
public static Function1<Object, Function1<String, Person>> curried() {
return Person..MODULE$.curried();
}
public static Function1<Tuple2<Object, String>, Person> tupled() {
return Person..MODULE$.tupled();
}
public static Person apply(int paramInt, String paramString) {
return Person..MODULE$.apply(paramInt, paramString);
}
public static Option<Tuple2<Object, String>> unapply(Person paramPerson) {
return Person..MODULE$.unapply(paramPerson);
}
}
对
Person$.class
编译如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 import scala.Option;
import scala.Serializable;
import scala.Some;
import scala.Tuple2;
import scala.runtime.AbstractFunction2;
import scala.runtime.BoxesRunTime;
public final class Person$
extends AbstractFunction2<Object, String, Person>
implements Serializable {
public static final MODULE$;
private Person$() {
MODULE$ = this;
}
private Object readResolve() {
return MODULE$;
}
public Option<Tuple2<Object, String>> unapply(Person x$0) {
return x$0 == null ? None..MODULE$:
new Some(new Tuple2(BoxesRunTime.boxToInteger(x$0.age()), x$0.name()));
}
public Person apply(int age, String name) {
return new Person(age, name);
}
public final String toString() {
return "Person";
}
static {
new ();
}
}
Student.scala
源码,运行后生成Student$.class
和Student.class
两个文件。
1
2
3
4
5
6
7
8 class Student(val age:Int, val name:String){}
object Student{
def main(args: Array[String]): Unit = {
val stu = new Student(25, "stm")
println(stu)
}
}
对
Student.class
反编译如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import scala.reflect.ScalaSignature;
public class Student {
private final int age;
private final String name;
public Student(int age, String name) {
}
public String name() {
return this.name;
}
public int age() {
return this.age;
}
public static void main(String[] paramArrayOfString) {
Student..MODULE$.main(paramArrayOfString);
}
}
对
Student$.class
反编译如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import scala.Predef.;
public final class Student$ {
public static final MODULE$;
static {
new ();
}
public void main(String[] args) {
Student stu = new Student(25, "stm");
Predef..MODULE$.println(stu);
}
private Student$() {
MODULE$ = this;
}
}
从编译结果,可以看出一下几点:
生成了
apply
方法,可以直接把对象当做方法使用。1
val person = Person(25,"stm")
继承了
Product
和Serializable
。age
和name
是用final
修饰的。- 默认实现了
toString
。 实现了
name()
和age()
方法。(参数列表中的参数都隐式获得一个val
作为前缀)1
2println(person1.age) //25
println(person1.name) //stm重写了
equals
方法,比较structure
而不是reference
:1
2
3val person1 = Person(25, "stm")
val person2 = Person(25, "stm")
println(person1 == person2) //true
case object
与case class
区别
case object
反编译后没有apply
和unapply
方法,因为caes object
没有参数。
总结
case class
和case object
本质没区别,有参使用case class
,无参使用case object
;case class
和case object
增加了继承和方法。case class
和case object
支持模式匹配。