Help us understand the problem. What is going on with this article?

[Java]新人向けにJavaBeansの直列化やフィールド・プロパティの謎をPOJOとの違いを交えて解説

More than 3 years have passed since last update.

はじめに

JavaBeansに関する質問・疑問

JavaBeansってSerializable インターフェースを実装する必要あるんですか?

  • 答えは「あります」です。
  • まず、java.io.Serializable インターフェースを実装することで、当該クラスは直列化可能となる訳ですが。
  • JavaBeansは「直列化可能である」ということが仕様となりますので、直列化可能とするためにjava.io.Serializable インターフェースを実装する必要があります。
  • Serializable インターフェースが実装されてないBeanっぽいクラスを見かけますが、JavaBeansの仕様から外れるので、それはPOJO(Plain Old Java Object)です。
  • POJOは、特定のルールや制約、アーキテクチャに縛られていない単純なJavaオブジェクトと覚えれば良いでしょう。

ところでJavaBeansって何のために直列化するの?

  • 直列化については、[Java]java.io.SerializableのSerializable(直列化可能)とは何なのか? を参照してもらうのが良いと思います。(以下で引用させてもらってます)
  • まず、直列というのは、”「オブジェクトを1次元のデータ列に変換(シリアライズ)出来たり、そこからオブジェクトを復元(デシリアライズ)する」” こととなります。
  • 例えば、お馴染みのStrutsのActionFormでは、Sessionに入れたオブジェクトをメモリからディスクに書き出すことがあるため、JavaBeansの仕様を満たす必要があります。クラス ActionForm
  • というのもTomcatでは再起動やリロードの際に、セッションの直列化と復元を行っていて、それに乗っかるフレームワークはJavaBeansの仕様を必要とします。
  • これによって、Tomcat の再起動後、再度アクセスされた場合でも、JavaBeansで実装されたセッションオブジェクトが再利用可能となるといった嬉しいことが起こっています。(混乱するのでプロパティエディタについては触れません)

JavaBeansのフィールドの定義とプロパティの定義が謎すぎます。

  • 例えば、Humanクラスに name というフィールドがある場合、お馴染みのアクセッサメソッド(getter/setter) である setNamegetName がプロパティの定義となり、setとgetを除くNameの頭1文字を小文字にした 'name' がプロパティとなります。(一旦 isXXX については言及してません)
  • ここまではピンときますが、JavaBeansの仕様的に「フィールド=プロパティ」とはなりません。という一言で参加者は一気にJavaBeansの闇に陥り落ちいりました。
  • 回答としては、JavaBeansの仕様的には 命名規則に従ったgetter/setterをもつ なので厳密には「フィールド=プロパティ」とはなりません。
  • 要するに「JavaBeans でのフィールドとプロパティを混同しないでください」と解釈できます。
  • 結局のところカプセル化されているJavaBeansをフレームワークが利用する場合、外部からフィールドに直接アクセスされることはなく、アクセッサメソッドであるプロパティが使われるので、フィールドが何であろうとJavaBeans的には問題ありません。
  • 以下の実装の場合は、「nenrei」というint型のread-writeプロパティを持っているJavaBeansとなります。外部からフィールド(age)がどんな名前であろうと問題となりません。
Human.java
public class Human implements Serializable {

  private int age; // フィールド

  /**
   * setNenreiとgetNenreiが「nenrei」プロパティ定義
   */
  public void setNenrei(int nenrei) {
    this.age = nenrei;
  }
  public int getNenrei() {
    return this.age;
  }

}
  • 但し、一般的には原則として「フィールド=プロパティ」であり、「フィールド≠プロパティ」としても、利用者を混乱させたり、不快な思いにさせてしまうので、相当な理由がない限り「フィールド=プロパティ」としましょう。

結局のところJavaBeansとは

  • 本に記載されている通り、Javaのクラスの独立性を高め、部品として再利用しやすくするために以下のルールを守っているクラスです。
    • ルール①:直列化可能である(java.io.Serializable インターフェースを実装している)。
    • ルール②:クラスはpublicパッケージに所属する。
    • ルール③:publicで引数のないコンストラクタをもつ。
    • ルール④:フィールドはカプセル化(隠蔽化)されている。
    • ルール⑤:命名規則に従った setter/getter をもつ。
  • 元々、クライアント(GUIを実装した)で実行することを意識したコンポーネント技術ですが、上記のルールを活用して、サーバーサイドを含む様々なフレームワークが利用しています。
  • 前途の質問・回答を読んだ後なら理解が深まるのではないでしょうか。
  • コードは載せた方が良いので適当なコードを貼っておきます。
SampleBean.java
package trial;

import java.io.Serializable;

public class SampleBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private int id;
    private String title;
    private String author;

    public SampleBean() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

}
ukitiyan
ここでの記載内容は個人の見解であり、所属する団体の公式見解ではありません。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away