如何以编程方式确定该类是一个案例类还是一个简单的类?

时间:2011-09-23 06:32:28

标签: class scala

如何以编程方式确定给定的类是案例类还是简单类?

3 个答案:

答案 0 :(得分:22)

使用新的Scala反射API:

scala> class B(v: Int)
defined class B

scala> case class A(v: Int)
defined class A

scala> def isCaseClassOrWhat_?(v: Any): Boolean = {
     |   import reflect.runtime.universe._
     |   val typeMirror = runtimeMirror(v.getClass.getClassLoader)
     |   val instanceMirror = typeMirror.reflect(v)
     |   val symbol = instanceMirror.symbol
     |   symbol.isCaseClass
     | }
isCaseClassOrWhat_$qmark: (v: Any)Boolean

scala> class CaseClassWannabe extends Product with Serializable {
     |   def canEqual(that: Any): Boolean = ???
     |   def productArity: Int = ???
     |   def productElement(n: Int): Any = ???
     | }
defined class CaseClassWannabe

scala> isCaseClassOrWhat_?("abc")
res0: Boolean = false

scala> isCaseClassOrWhat_?(1)
res1: Boolean = false

scala> isCaseClassOrWhat_?(new B(123))
res2: Boolean = false

scala> isCaseClassOrWhat_?(A(321))
res3: Boolean = true

scala> isCaseClassOrWhat_?(new CaseClassWannabe)
res4: Boolean = false

答案 1 :(得分:2)

目前(2011年),您可以使用反射来确定该类是否实现了接口scala.Product

scala> def isCaseClass(o: AnyRef) = o.getClass.getInterfaces.find(_ == classOf[scala.Product]) != None
isCaseClass: (o: AnyRef)Boolean

scala> isCaseClass(Some(1))
res3: Boolean = true

scala> isCaseClass("")
res4: Boolean = false

这只是一个近似值 - 你可以更进一步检查它是否有copy方法,如果它实现Serializable,是否有一个具有适当apply的伴随对象或unapply方法 - 实质上,使用反射检查案例类中预期的所有内容。

下一版本中的scala反射包应该使案例类检测更容易,更精确。

编辑:

您现在可以使用新的Scala Reflection库来执行此操作 - 请参阅其他答案。

答案 2 :(得分:2)

如果您的意思是:我可以通过编程方式确定某个类是案例类还是非案例类,答案是否定的,但您可以进行近似。 Case类只是一个编译器hack,它们告诉编译器创建某些方法等。在最终的字节码中,普通类和case类没有区别。

来自How does a case class differ from a normal class?

  
      
  1. 您可以对其进行模式匹配,
  2.   
  3. 您可以在不使用new的情况下构造这些类的实例   关键字,
  4.   
  5. 所有构造函数参数都可以从外部使用   自动生成的访问者功能,
  6.   
  7. 自动重新定义toString方法以打印名称   案例类及其所有参数,
  8.   
  9. 自动重新定义equals方法以比较两个   结构上而不是同一性的同一案例类的实例。
  10.   
  11. 自动重新定义hashCode方法以使用   构造函数参数的hashCodes。
  12.   

因此,您只需定义正确的方法即可创建案例类。伴侣自己。

如果想知道如何将作为案例类,请查看axel22的答案。