首页 > 解决方案 > 如何更改案例类的基类属性

问题描述

采取以下代码:

class A(val i: Int)

case class B(str: String) extends A(1)

val b = B("test")

在我的场景中,我受到无法更改的 B 定义的限制。我也希望避免重构 B,因为我有许多这样的对象,它们的属性比这个例子中的要多得多。

有什么方法可以创建一个新的 b 副本(使用反射或其他方式),并为 i 设置一个新值?

相当于:

val b2 = b.copy(i = 2)

注意:问题是可以做到吗?不是最好的编程实践。

标签: scala

解决方案


您可以使用反射来做到这一点,如下所示:

  val b = B("foo")
  val c = b.copy()
  println(b.i) // prints 1
  val field = classOf[A].getDeclaredFields.head
  field.setAccessible(true)
  field.setInt(c, 2)
  println(c.i) // prints 2

但请注意,这不仅仅是“糟糕的编程习惯”,而是完全违反合同

您的声明case class B(s: Sting) extends A(1)承诺所有实例B始终i等于 1,这是一个谎言。

更不用说,有趣的事实,比如b == c成为truec.copy.i成为 1 等。不要这样做。


推荐阅读