当一个类被声明为case calss时,编译器会自动进行如下操作:
1)构造器中的参数如果不被声明为var,默认是val类型的。
2)自动创建伴生对象,同时在伴生对象中实现apply方法,这样在使用的时候可以不直接显式地来创建new对象。
3)伴生对象中同样可以实现unapply方法,从而可以将case class应用于模式匹配。
4)实现自己的toString、hashCode、copy、equals等方法。
例4-12给出了一个Case Class与模式匹配使用示例。该例是case class与模式匹配结合使用的示例,使用case class最大的好处是不需要手动定义unapply方法。
【例4-12】Case Class与模式匹配示例。
代码执行结果如下:(www.daowen.com)
通过代码运行结果可以看到,直接使用构造器模式便可以将对象内容提取出来。这里的构造器模式其实调用的是unapply方法。为验证模式匹配时,后面的实现原理确实是通过unapply方法来实现的,这里对Student类生成的字节码文件进行反编译,Student类编译后生成两个字节码文件,分别是Student$.class(编译器自动生成的Student伴生对象对应的字码节文件)、Student.class(Student类本身对应的字节码文件),利用javap命令进行反编译后内容如例4-13所示。
【例4-13】case class Student生成的字节码反编译后的结果示例。
通过反编译的字节码文件可以看到,将类声明为case class,编译器会自动帮我们生成若干方法,在本例中最重要的方法是apply方法及unapply方法。Aplly方法用于不直接使用new显式创建对象,而unapply方法则用于在模式匹配时对对象进行析取。从例4-14反编译后的结果可以看到,编译器确实为Student类生成了对应的apply、unapply及其他相关方法。为验证背后的实现原理,在Student类中自己定义apply及unapply方法,从而使其能够用于模式匹配,代码如例4-14所示。该例将Student类定义为普通类,通过自己手动在伴生对象Student中定义apply方法和unapply方法,以使Studnt类能够用于模式匹配。
【例4-14】自己定义unapply方法使Student类能够用于模式匹配示例。
代码执行结果如下:
如结果所示,代码运行结果同例4-13一样。例4-14的第1行代码,定义了一个普通的Student类,第2行至第10行,定义了Student类的伴生对象,并定义了其apply及unap⁃ply方法,第11行至第20行演示了模式匹配的使用方法,在执行第16行代码case Student(name,age,studentNo)时会调用Student伴生对象的unapply方法,这一点可以通过程序调试得到的验证。不难看出,自己定义unapply方法的普通Student类与case class Student类在使用上没有任何差别,后面的实现原理是一致的,只不过定义为case class,编译器会自动处理很多事情,从而简化了程序设计。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。