采用以下代码:
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)
注意:问题是可以做到吗?并不是最佳的编程实践。
答案 0 :(得分:1)
您可以使用反射来完成此操作:
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
为true
或c.copy.i
为1等。
不要这样
答案 1 :(得分:0)
如果您以这种方式定义B
,则不会。但是这段代码对我有用:
class A(val i: Int)
case class B(str: String, override val i:Int=1) extends A(i)
val b = B("test")
val b2 = b.copy(i = 2)
P.S。从技术上讲,您可以不做任何修改就直接复制,然后使用反射来编辑i
,但这不是个好主意。
答案 2 :(得分:0)
您可以这样做:
val b2 = new B(b.str) { override val i = 2 }
不利之处在于,您必须根据大量参数来重新构建B
。