日々常々

ふつうのプログラマがあたりまえにしたいこと。

JavaBeansって言葉に煩わされない

JavaBeansって言葉を目にして、ふと検索してみたらあまりに酷かったので書いておこうかと。対象は「JavaBeansってなんだろ?」と思ってしまった初学者さん。でもそんな人って私のブログ読むんだろうか……

今後は「このエントリ参照」にするつもりで書いてみる。 文字列連結と+演算子について整理しておく みたいな感じ。

ShortAnswer

JavaBeansを学ぶ必要はありません。JavaBeansと説明されているものの多くは、JavaBeansの名前を借りた独自の物体です。

長い説明

「あまりに酷い」と「要らない」だけだと流石にアレなので、仕様を斜め読みしながら説明していきます。あ、EJBには触れません。まぜるなきけん。

仕様について

JavaBeans仕様としてげったーせったーがーとか、こんすとらくたがーだとか、しりあらいざぶるがーだとか。よく見聞きするのだけど、仕様って読んだんだろうか……いや、嘘は書いてないけど、大事なところを落として話してる気がしてならない。仕様の話をするなら仕様へのリンクくらいつけて欲しいものです。

なお仕様は JavaBeans(TM) Specification 1.01 Final Release から入手できます。114ページもある英語の文章なんて読めない?私もです。

What is a Bean?

JavaBeansってなんなのよって話。再利用可能が云々とかはよく見ると思います。

で、7ページのIntroductionにはこう書かれてて。

The goal of the JavaBeans APIs is to define a software component model for Java, so that third party ISVs can create and ship Java components that can be composed together into applications by end users.

コンポーネント、なんですよね……なんでデータコンテナにすり替えられるのか。自分の理解している何かを置き換えたかったからなんだろか。まあコンポーネントってなんぞよみたいなところもあるんでスルーするとして。

これはこれとして、9ページに「What is a Bean?」ってまんまなのがあります。これは画像で。

f:id:irof:20190725113645p:plain

こんだけあからさまに太字で場所とって書かれてる。

A Java Bean is a reusable software component that can be manipulated visually in a builder tool.

ビルダーツールでビジュアリーにマニュピレートできる、ってさ。ビルダーツールってあれですよ、ドラッグドロップして線とか繋いで、プロパティをプルダウンとかからいじったりして、とかするあれ。最近だとiOSアプリ触るときに使ったかな……あれはUIもセットだけど。まあ、ビルダーツール使って視覚的に操作するためのものなのです。

もう「よく言われるJavaBeans」がJavaBeansに関係ないことわかりましたかね。これに触れずにJavaBeansがどうとか意味ないと思うんですよ。

JavaBeansの使われ方

12ページにこんな図があります。

f:id:irof:20190725120302p:plain

Local activationの項目で出てきてる図なので使われ方として示すのは不適切かもしれないけど。JavaBeanがただのデータの入れ物じゃないってのはわかるかと思います。

ところでこの図のJavaBeans ApplicationをFaaS(AWS Lambdaとか)って書いたらなんかイマドキっぽくないですか?あ、CORBA……何もかも懐かしい(Java11から目線)

あと java.beans.BeanInfo インタフェース

Beanの情報としてBeanInfoインタフェースがございます。仕様だと60ページとかなんですが、インタフェースなんでJavadocでもみれます。

BeanInfoって名前なんだから、Beanの情報として求められるものです。MethodDescriptorsとかPropertyDescriptorsとかはまあいいんですが、輝くのは getIcon​(int iconKind) メソッドですね。Beanならアイコンあるよね?とか言ってくるわけです。だってビルダーツールで操作するんだから。

と言うことでJavaBeansの必要条件をみてみると

WikipediaBeanの必要条件とかに書かれているようなのはこう言うことで。

  • デフォルトコンストラクタが必要なのは、ビルダーツールでインスタンス生成するため。コンストラクタ複数あったりすると作るのに手間取るからね。 で、必要ならデフォルトコンストラクタでプロパティのデフォルト値設定しとけと。
  • getter/setterが必要なのはフィールドを公開するためじゃなく、ビルダーツールにプロパティを表示するためのgetterと変更したときに呼ぶsetter。プロパティの変更イベントも処理できるよ。
  • シリアライズが要るのはビルダーツールで作ったコンポーネントの保存と復元をするため。

全部ビルダーツールで操作するためでございます。

触れなかったけど

イベントモデルとか図眺めてるだけでも面白い。英語でもクラス名とか図とかあったら私でも読める。

JavaBeansって言葉がよく使われた理由の憶測

ビルダーツールから操作しやすい条件が、当然のように他のフレームワークやライブラリからも操作しやすかったからだと思います。なので独自に定義せずにJavaBeans仕様に乗っかったインスタンス操作ツールがぽこぽこ出てきました。小さいものの組み合わせではなく、包括しているものから拝借する感じ、1990-2000年代だなー感ありますね。

先に挙げた条件(デフォルトコンストラクタとsetter/getterがセットであること)は機械的に操作するにはもってこいだったのでしょう。で、setter/getterを介して操作しようとすると、メソッドをリフレクションで拾ってくるとかになるわけで(PropertyDescriptorとかは使われず……内部では使ってたりするのでセットでなかったらエラーになったりする。)、他のメソッドがあったらエラーになったりしたんです。

リフレクションでこの辺処理するツール作ったことある人ならわかると思うんですが、メソッドをとってきてsetter/getterを並べるより、フィールドをとってきてそのsetter/getterを命名規則で処理するほうが楽なんですよね。なのでフィールドとsetter/getterの名前を合わせる、みたいな流れも生まれたし、フィールドには全てsetter/getterを作る、とかもできたわけで。ツールの怠慢と言えなくもないですが、それでなぜか「フィールド名と一致するsetter/getterがないと落ちる」「setter/getter以外のメソッドがあると誤作動する」から「フィールドとsetter/getter以外は作らない」とかよくわからない方向にいって、現在のlombok使わないとめんどくさいようなゴミができあがったんじゃないでしょうか。あ、ゴミって言っちゃった……。

最後に

というわけで、1997年の話でした。22年前。JavaBeansは、現在のJavaを使用したアプリケーション開発の主な文脈では、取り立てて重要なところは担っていません。(内部では使ってたりしますが、「JavaBeansであること」を求めてはないはずです。おそらく単に便利だから使ってる程度。)

最初に「学ぶ必要がない」と書いたのは、「JavaBeansについて知る」をJavaの勉強の直下におく必要がないと言うことです。他のタイミングで java.beans パッケージを使用していたら、あーJavaBeansってのを使ってるんだなーから、そのクラスやライブラリがどんな使い方をしているかを調べるって感じでいいと思います。

「JavaBeansはJavaの基本だろ?」とか言ってよくわからない説明をしているものに惑わされないでください。