• 作成:

Scalaで定義したcase classのcopyをJavaから呼び出したかったが無理なのでcloneで妥協しました

copyは実に良いメソッドです. Haskellのレコードのフィールド更新やJavaScriptのスプレッド構文のように使えます.

でも何故かJava側から呼び出せなくて困惑しました. ScalaのメソッドはJavaからスムーズに呼び出せるはずなのに.

よく考えてみるとcopyメソッドはメソッドのデフォルト引数機能の存在を前提としたメソッドで, Javaにはデフォルト引数機能が無いんですね.

このままでは既存のcloneを使ったコードが壊れてしまうのでScalaを使えない…

と思いましたが, 冷静に考えてみるとJava向けにはcloneを実装してやれば良い話ですね.

case class Foo() extends Cloneable {
  override def clone(): Foo = {
    copy()
  }
}

これでJavaとの互換性を壊すことなく解決しました.

しかしそもそもJavaにレコード更新機能があれば流石に再実装はしなかったのですが. デフォルト引数機能が無いのでリフレクションやアノテーションを駆使しても自然に実装するのは難しそう. 出来たとしてもメソッドが大量に生まれる… それならLombokの@Dataみたいなのを使った方が良さそうですね.

cloneしてsetterを動かせば良い? 面倒臭さを除けばそうですね.

将来的にJavaにもレコードが導入されるらしいのですが, JEP 359: Records (Preview) 更新機能もちゃんと導入されると良いですね.