Javaのsealedクラス、公開APIで使うと実行時に壊れる罠

Java sealed classes and exhaustive pattern matching

Java 17のsealedクラスは全ケース網羅をコンパイラが保証してくれるが、それは利用側を再コンパイルした場合に限られる。公開APIにsealed型を露出させると、サブタイプ追加のたびに利用側が壊れ、しかも再コンパイルされなければMatchExceptionが実行時に飛ぶ。著者はPEM暗号オブジェクトのプレビューAPIがまさにこの過ちを犯していると指摘する。

sealed型はコンポーネントの実装内部でこそ最も有用で、ライブラリのように外部へ公開するAPIでは有用性が低い。
  1. shepherdjerred

    Javaがここまで進化したのは本当に素晴らしい。フロントエンドの仕事が多いので、スタック全体で同じ言語を使いたいから、自分は今でもTypeScriptの方が好きだけどね。

    そうは言っても、TypeScriptでも網羅的なパターンマッチングができるんだ!https://github.com/gvergnaud/ts-pattern

  2. armchairhacker

    Javaには再帰パターンと、(まだプレビューかもしれないが)リテラルパターンもある:`switch (x) { case A(B(true, var c)) -> f(c); }`

  3. another_twist

    sealedに慣れるまで時間がかかったし、使い道がよくわからなかった。でもAIがJavaでsealedをやたら好むみたいなので試してみたら、今は理解できた。特にDIを使っていて非推奨にしたいものがある場合、これは本当に優れたアクセス制御の仕組みだと思う。もちろんパターンマッチングは、ペイロードの形が変わるイベント駆動メッセージで重宝するけどね。

  4. timshel2

    Scalaが今ごろ悔しがってるよ

  5. panny

    sealed型を使うなら、そういうswitchのdefaultは必要ないと思う。コンパイラで確認したわけじゃないけど、不要だと思うよ。

  6. Larrikin

    JavaはKotlinに追いつこうとし続けている

    https://kotlinlang.org/docs/sealed-classes.html

    比較対象がC++やRuby、Pythonだった頃はJavaも悪くないと思ってた。でもScala(無差別すぎて失敗したように見えた)を経て、特にKotlinの後では、戻る理由が見つからない。

この日のほかの記事

2026-10-18