連載
» 2004年04月17日 00時00分 公開

JavaBeansのルールを知る基礎から学ぶサーブレット/JSP(12)(2/2 ページ)

[山田祥寛,@IT]
前のページへ 1|2       

JavaBeansであるための2つの条件

 さて、サンプルの動作を確認したところで、「JavaBeansであるための2つの構文規則」の部分に焦点を絞って、解説していくことにしましょう。

 もっとも、「構文的な規則」といったところで、何ら特殊なものでも難しいものでもありません。JavaBeansとは「再利用性を高めるために、ある一定の構文規則にのっとって記述された」という以外には、まったく普通のクラスにほかなりません。

条件1:引数のないコンストラクタが定義されていること

 「コンストラクタ」(注)とは、クラスがインスタンス(オブジェクト)化される際に呼び出される特殊なメソッドで、クラス名と等しい名前を持ちます。SendMailクラスにおいては、以下の部分がコンストラクタに当たる部分です。その性質上、コンストラクタでは、クラス内の各種フィールド(変数)の初期化などを行うのが一般的です。

public SendMail(){
  this.smtp="smtp.xxxxx.ne.jp";
}

注:コンストラクタに関する詳しい解説は連載:いまから始めるJava「第5回 メソッドとコンストラクタはなぜ必要?」を参考にしてください。

 一見、普通のメソッドと同じように見えるため、間違えやすい点でもありますが、コンストラクタにおいては、戻り値のデータ型を宣言することはできません。つまり、上記の例でいけば、

public void SendMail(){
  this.smtp="smtp.xxxxx.ne.jp";
}

のような記述は間違いであるということです。戻り値のデータ型を記述してしまった場合、コンストラクタは通常のメソッドであると見なされ、また、コンパイル時にも警告などは表示されませんので、注意してください。

 以下は、コンストラクタの一般的な構文です。

[修飾子] クラス名(){
  // コンストラクタ内の定義
}

 JavaBeansでは、このコンストラクタに引数を持たせることができません。例えば、皆さんもおなじみのStringTokenizerクラスなどは、

StringTokenizer objTkn=new StringTokenizer(strVal,"\t");

のように、インスタンス化に際して必ず引数を指定する必要があります。しかし、JavaBeansのインスタンス化に際しては、

JavaBeans名 オブジェクト変数=new JavaBeans名();

の形式で呼び出すことができなければならないということです。

 ちなみに、コンストラクタとして特に変数の初期化などが必要ないという場合には、コード上、記述を省略することも可能です。その場合、コンパイル時に「引数のない、空のコンストラクタ」が自動的に生成されます。

One Point

JavaBeansは引数を持たないコンストラクタを持つ必要があります。コンストラクタとは、クラスのインスタンス化に際して実行される特殊なメソッドのことで、主にプロパティ(変数)やクラス内で使用するリソースの初期化などを行います。


条件2:プロパティを参照・設定するためのアクセサメソッドが定義されていること

 例えば、以下のようなクラス定義があったとします。

public class SampleClass {
  public String value;
}

 この場合、SampleClassクラス内の変数valueには、以下のようにアクセスすることができます。

SampleClass objCls=new SampleClass();
objCls.value="hogehoge";

 SampleClassクラスの変数valueは、アクセス修飾子として「public(どこからでもアクセス可能)」が指定されていますので、外部からの呼び出しに際しても直接にアクセスできるというわけです。

 しかし、JavaBeansから変数(プロパティ)を公開するに際しては、これは許されません。JavaBeansでは、変数自体は必ずアクセス修飾子「private」として定義しなければならないのです。private変数は「クラス内からのみ参照・設定が可能な」変数ですので、外部からは直接にアクセスすることはできません。

 そこで、private変数にクラスの外部からアクセスするためのgetXxxx、setXxxxという名前のメソッドを用意する必要があります。このgetXxxx、setXxxxメソッドを総称して「アクセサメソッド(Accessor Method)」といいます。getXxxx、setXxxxメソッドの「Xxxx」の部分は、必ずprivate変数の頭文字を大文字にしたものでなければなりません。

 上記のSampleClassクラスをアクセサメソッドを利用して書き直してみましょう。

public class SampleClass {
  private String value;
  // valueプロパティ設定用のメソッド(setterメソッド)
  public void setValue(String value){
    this.value=value;
  }
  // valueプロパティ取得要のメソッド(getterメソッド)
  public String getValue(){
    return this.value;
  }
}

 上記は非常に簡単な例ですが、アクセサメソッドを介してプロパティにアクセスさせることには、以下のようなメリットがあります。

(1)読み書きの可否を制御できる

 アクセス修飾子で指定できるのは、あくまで該当する変数(プロパティ)に対する「アクセス範囲」だけです。そのプロパティが読み取り専用である、書き込み専用であるといった制御までは、アクセス修飾子は対応していないのです。しかし、アクセサメソッドを介することで、こうした読み書きの可否を明確に宣言できます。

setterメソッドの有無 getterメソッドの有無 プロパティの扱い
読み書き可能
× 書き込みのみ可能
× 読み取りのみ可能
× × JavaBeans内部でのみ使用可能

(2)値の設定時にデータの妥当性を検証できる

 変数(プロパティ)それ自体として定義できるのは、あくまでデータ型のみです。つまり、同じ文字列型でも「50文字以内である」といった制約を、データ型が表すことはできません。しかし、アクセサメソッド(setterメソッド)を介することで、値の設定時にデータの内容を検証することが可能になります。また、もしもプロパティに対して不正な値が設定されていた場合にも、setterメソッド内部でエラー処理をしたり、既定の値を自動的にセットすることが可能になります。

(3)内部的なデータの持ち方が変更されても、外部に影響を与えない

 例えば、開発の途中で変数valueのデータ型がStringからintに変更されたとしたらどうでしょう。もしも変数に対して外部から直接にアクセスしていたとしたら、JavaBeansを利用するすべてのコードに影響が及ぶことになります。当然、修正の個所が多くなれば、修正漏れも発生すれば、バグを引き起こす原因にもなるでしょう。

 しかし、この問題もアクセサメソッドを介することで解決されます。getterメソッドの内部でint型をString型に変換してやればよいのです。そうすれば、外部に対しては何らデータ型を変更したことによる影響を与えることはありません。JavaBeansそれ自体のみを修正すれば万事OKです。

図2 アクセサメソッドを使ったアクセス 図2 アクセサメソッドを使ったアクセス

One Point

JavaBeansのプロパティは、必ずアクセサメソッドを介して公開される必要があります。アクセサメソッドは、値参照用のgetterメソッド、設定用のsetterメソッドの総称です。


 今回はJavaBeansを利用した実践的なサンプルを動かしてみると同時に、JavaBeansの構文的な規則にフォーカスして解説しました。しかし、繰り返し述べているように、JavaBeansとはJSPやサーブレットと連携して初めて、意味があります。

 次回は、今回ご紹介できなかったJavaBeansとJSP&サーブレットの連携に焦点を絞って、引き続き詳細を解説します。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。