本章では、配列、コレクションと並び、Javaのデータ保持の手法の1つでもある「JavaBeans」について学習します。
本章で学習する内容を動画としてまとめたものです。最初に一通り見終わった後で、学習に入るようにしてください。
JavaBeans(ジャバビーンズ)は、ある一定のまとまった情報を1つのオブジェクトとして扱いたい場合、これまでとは若干異なるクラスの使い方をすることで実現します。
複数の値を保持する機能として、これまで配列とコレクションを学習してきました。配列やコレクションは、主に同じ型のデータを格納するために使用されます。
ここで学習するJavaBeansは、異なるデータ型の値をまとめて保持する機能になります。
例えば、会員情報の会員番号、氏名、住所、電話番号を1つのJavaBeansのオブジェクトにまとめて保持することができます。
それでは、実際にJavaBeans(以降Beanと記載します)を使用する場合と使用しない場合で、どの程度の違いがコードに表れるかサンプルを通して学習していきましょう。
以下のサンプルソースを見てください。
import java.util.ArrayList;
import java.util.List;
public class NotBeanSample1 {
public static void main(String[] args) {
// 情報を保持するリストオブジェクトを生成
List<String> nameList = new ArrayList<String>();
// 名前をリストオブジェクトに追加
nameList.add("佐藤");
nameList.add("伊藤");
nameList.add("鈴木");
// リストに追加した情報をコンソールに出力
for (String name : nameList) {
System.out.println("名前は" + name + "です。");
}
}
}
この例ではListオブジェクトに対して、「佐藤」、「伊藤」、「鈴木」という複数の名前を格納し、保持しています。
次の例では名前の他にフリガナと年齢も加えたパターンのサンプルです。
import java.util.ArrayList;
import java.util.List;
public class NotBeanSample2 {
public static void main(String[] args) {
// 名前を保持するリストオブジェクトを生成
List<String> nameList = new ArrayList<String>();
// フリガナを保持するリストオブジェクトを生成
List<String> furiganaList = new ArrayList<String>();
// 年齢を保持するリストオブジェクトを生成
List<Integer> ageList = new ArrayList<Integer>();
// 佐藤さんの情報を各リストに追加
nameList.add("佐藤");
furiganaList.add("サトウ");
ageList.add(19);
// 伊藤さんの情報を各リストに追加
nameList.add("伊藤");
furiganaList.add("イトウ");
ageList.add(30);
// 鈴木さんの情報を各リストに追加
nameList.add("鈴木");
furiganaList.add("スズキ");
ageList.add(25);
// 各リストに追加されている各情報を同じインデックスで出力
for (int i = 0;i < nameList.size();i++) {
System.out.println("名前 : " + nameList.get(i));
System.out.println("フリガナ : " + furiganaList.get(i));
System.out.println("年齢 : " + ageList.get(i));
System.out.println("");
}
}
}
このように、複数の値を1つのまとまりとして扱い、保持する場合、実装方法次第で多数のコレクションや配列を複数個使用する形になってしまいます。
Beanを使用すればこういった問題を解決し、複数の値を1つのまとまりとすることが可能です。
では、次にBeanを使用したサンプルを解説します。
作成するクラスは、Beanクラスと、Beanクラスを呼び出すクラスの2つとなります。
以下はBeanクラスのサンプルコードです。
public class SampleBean {
// 名前
private String name;
// フリガナ
private String furigana;
// 年齢
private int age;
/**
* 名前を取得するメソッド
*/
public String getName() {
return name;
}
/**
* 名前を設定するメソッド
*/
public void setName(String name) {
this.name = name;
}
/**
* フリガナを取得するメソッド
*/
public String getFurigana() {
return furigana;
}
/**
* フリガナを設定するメソッド
*/
public void setFurigana(String furigana) {
this.furigana = furigana;
}
/**
* 年齢を取得するメソッド
*/
public int getAge() {
return age;
}
/**
* 年齢を設定するメソッド
*/
public void setAge(int age) {
this.age = age;
}
}
これがBeanクラスとなります。これまでと同じようにフィールドがあり、メソッドのある通常のクラスです。
ただ、サンプルソースを見ても分かるように、格納したい値に対して各フィールドをそれぞれ定義しています。
今回のサンプルの場合、名前、フリガナ、年齢を保持するために、name、furigana、ageと3つのフィールドが定義されています。
また、通常Beanクラスは、データ保持用のクラスであるため、各フィールドにprivateをつけてアクセスの制限を設けます。
Beanのオブジェクトの各フィールドに値を格納したり取得するためには、1フィールドに対して
setフィールド名(引数のデータ型 引数の変数);
getフィールド名();
というように、2つのメソッドが対になって存在することに注目してください。
これは「setter」と「getter」と呼ばれるもので、privateで宣言されているフィールドに対してのアクセスメソッドです。
メソッド名から分かるとは思いますが、「setフィールド名(引数のデータ型 引数の変数);」がsetterで、「getフィールド名();」がgetterです。
「setter」は対象のフィールドに対して値を設定するもので、引数を必要とします。その処理はサンプルを見れば解りますが、引数の値をフィールドに対して代入しています。
「getter」は対象のフィールドの値を返す(取得する)もので、こちらは引数を必要としません。処理内容は対象のフィールドの値を返します。
補足ですが、フィールドとgetter、setterがセットで存在するものをプロパティと呼びます。
上記サンプルの場合、SampleBeanクラスに対して、以下のプロパティを作成したということになります。
JavaBeansの基本構成は、上記で説明したとおり、値を格納するためのフィールドと各フィールドのgetterとsetterとなります。
ただ、これを全部自分の手で記述するとなると、大変です。そこで、Eclipseの便利な生成機能を使うと良いでしょう。
Eclipseには、JavaBeansのgetterとsetterを自動的に記述してくれる機能があります。
各フィールドを定義した後、ソースの上を右クリックし、「ソース」⇒「getter および setter の生成」を選択してください。
以下のポップアップ画面が表示されますので、「すべて選択」ボタンを押下します。また、「メソッド・コメントの生成」にチェックを入れて、最後に生成ボタンを押下します。
これで、getterとsetterの基本構文が自動生成されます。JavaBeansを記述するときには活用してみましょう。
また、「メソッド・コメントの生成」にチェックを入れると、JavaDocコメントが自動的に付与されます。JavaDocコメントは「よく使うクラス」の章で説明していますので、忘れてしまった方は復習しましょう。
次にSampleBeanクラスを使ったサンプルです。
「佐藤さん」と「伊藤さん」、「鈴木さん」の名前、フリガナ、年齢を1つのListに格納し、保持し、出力します。
import java.util.ArrayList;
import java.util.List;
public class ShowSampleBeanPattern1 {
public static void main(String[] args) {
// 個人情報を保持するリストオブジェクト
List<SampleBean> infoList = new ArrayList<SampleBean>();
// 佐藤さんの個人情報を格納するBeanオブジェクトを作成し、リストオブジェクトに追加
SampleBean bean = new SampleBean();
bean.setName("佐藤");
bean.setFurigana("サトウ");
bean.setAge(19);
infoList.add(bean);
// 伊藤さんの個人情報を格納するBeanオブジェクトを作成し、リストオブジェクトに追加
bean = new SampleBean();
bean.setName("伊藤");
bean.setFurigana("イトウ");
bean.setAge(30);
infoList.add(bean);
// 鈴木さんの個人情報を格納するBeanオブジェクトを作成し、リストオブジェクトに追加
bean = new SampleBean();
bean.setName("鈴木");
bean.setFurigana("スズキ");
bean.setAge(25);
infoList.add(bean);
// 各個人情報をコンソールに出力
for (SampleBean bn : infoList) {
System.out.println("名前 : " + bn.getName());
System.out.println("フリガナ : " + bn.getFurigana());
System.out.println("年齢 : " + bn.getAge());
System.out.println("");
}
}
}
各個人情報を1つのBeanオブジェクトにまとめ、全ての情報を保持しているのは1つのリストオブジェクトです。
また、実際にBeanオブジェクトへの値の設定と、設定された値の取得をsetterとgetterにより行っています。
これまでに解説したBeanクラスは、値を設定して取得するといった、単純なBeanクラスでした。
そのため、setterとgetterを使用して値を設定、取得する場合と、直接フィールドから値を設定、取得する形式にBeanクラスを修正した場合(フィールドをprivateからpublicに変更)、同じ結果が返ってきます。
そのため、あまりメリットを感じられませんでした。
しかし、setterとgetterを作成することで、値の設定や取得を行う箇所の共通化を実現することができます。
例えば、以下のサンプルを見てください。
public class ShowSampleBeanPattern2 {
public static void main(String[] args) {
// 佐藤さんの名前が格納されたBeanオブジェクトを作成
SampleBean bean1 = new SampleBean();
bean1.setName("佐藤");
// 伊藤さんの名前が格納されたBeanオブジェクトを作成
SampleBean bean2 = new SampleBean();
bean2.setName("伊藤");
// 鈴木さんの名前が格納されたBeanオブジェクトを作成
SampleBean bean3 = new SampleBean();
bean3.setName("鈴木");
// 作成したBeanオブジェクトの情報を順序不同でコンソールに出力
System.out.println("最初に追加された名前は、" + bean1.getName() + "です。");
System.out.println("最後に追加された名前は、" + bean3.getName() + "です。");
System.out.println("2番目に追加された名前は、" + bean2.getName() + "です。");
}
}
このプログラムを実行すると、結果は以下になります。
最初に追加された名前は、佐藤です。
最後に追加された名前は、鈴木です。
2番目に追加された名前は、伊藤です。
プログラム作成後、コンソールに出力させる際に「名前に”さん”を付ける」という変更が発生した場合に、通常は、以下のような修正が行われる可能性が高いです。
public class ShowSampleBeanPattern3 {
public static void main(String[] args) {
SampleBean bean1 = new SampleBean();
bean1.setName("佐藤");
SampleBean bean2 = new SampleBean();
bean2.setName("伊藤");
SampleBean bean3 = new SampleBean();
bean3.setName("鈴木");
// 出力を行う際、名前とフリガナの後に「さん」を付ける
System.out.println("最初に追加された名前は、" + bean1.getName() + "さんです。");
System.out.println("最後に追加された名前は、" + bean3.getName() + "さんです。");
System.out.println("2番目に追加された名前は、" + bean2.getName() + "さんです。");
}
}
最初に追加された名前は、佐藤さんです。
最後に追加された名前は、鈴木さんです。
2番目に追加された名前は、伊藤さんです。
この修正内容でも問題は無いのですが、修正を行っている箇所が出力している3箇所全て、ということに着目して下さい。
サンプルでは3箇所しか存在していませんが、これが数十、数百箇所になってしまうと問題になります。
作業量が増加しますし、修正中のプログラミングミスによる別の問題が発生し兼ねません。
Beanを使用している場合、共通化のメリットを引き出すことによって、修正を行うためのプログラミングを極力減らすことが可能です。
この場合、名前を出力している箇所は全てgetNameメソッドを使用しています。
そのため、getNameメソッドを呼び出している箇所を修正するのではなく、getNameメソッド自体を修正してしまえば、修正箇所は1箇所のみで済むことになります。
修正は以下のようになります。
public class SampleBean {
private String name;
private String furigana;
private int age;
// 名前を返す際、名前に「さん」を付与する
public String getName() {
return name + "さん";
}
public void setName(String name) {
this.name = name;
}
public String getFurigana() {
return furigana;
}
public void setFurigana(String furigana) {
this.furigana = furigana;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
この修正後、修正前の状態だった「ShowSampleBeanPattern2」クラスを実行してみると、変更が反映された結果が出力されることが確認できます。
最初に追加された名前は、佐藤さんです。
最後に追加された名前は、鈴木さんです。
2番目に追加された名前は、伊藤さんです。
以上でJavaBeansの解説は終わりです。
それでは、Beanクラスを使った練習問題です。
以下の情報を格納するJavaBeansのInfoBeanクラスを作成してください。
変数名 | 説明 |
---|---|
name | 名前 |
address | 住所 |
job | 仕事 |
age | 年齢 |
InfoBeanクラスを作成後、実行するクラスも作成し、mainメソッドでInfoBeanクラスのsetter、getterを使用して以下のようにコンソールの出力を行ってください。
山崎
東京都千代田区
Javaプログラマ
20
public class InfoBean {
// 各フィールドを定義
private String name; // 名前
private String address; // 住所
private String job; // 仕事
private int age; // 年齢
// 名前を取得するメソッド
public String getName() {
return name;
}
// 名前を設定するメソッド
public void setName(String name) {
this.name = name;
}
// 住所を取得するメソッド
public String getAddress() {
return address;
}
// 住所を設定するメソッド
public void setAddress(String address) {
this.address = address;
}
// 仕事を取得するメソッド
public String getJob() {
return job;
}
// 仕事を設定するメソッド
public void setJob(String job) {
this.job = job;
}
// 年齢を取得するメソッド
public int getAge() {
return age;
}
// 年齢を設定するメソッド
public void setAge(int age) {
this.age = age;
}
}
public class BeanMondai1_1 {
public static void main(String[] args) {
// InfoBeanクラスのインスタンス化
InfoBean infoBean = new InfoBean();
// 名前を設定
infoBean.setName("山崎");
// 住所を設定
infoBean.setAddress("東京都千代田区");
// 仕事を設定
infoBean.setJob("Javaプログラマ");
// 年齢を設定
infoBean.setAge(20);
// 名前をコンソールに出力
System.out.println(infoBean.getName());
// 住所をコンソールに出力
System.out.println(infoBean.getAddress());
// 仕事をコンソールに出力
System.out.println(infoBean.getJob());
// 年齢をコンソールに出力
System.out.println(infoBean.getAge());
}
}
この問題では、JavaBeansを使用し、JavaBeansに設定した値をコンソールに出力しています。
作成したJavaBeansのInfoBeanクラスを使用し、値を格納する場合、まずインスタンス化を行います。
InfoBean infoBean = new InfoBean();
インスタンス化したInfoBeanクラスのオブジェクトの各フィールドに値を設定するには、setterメソッドを使用しましょう。
infoBean.setName("山崎");
また、格納した値を取得する場合、getterメソッドを使用します。
System.out.println(infoBean.getName());
問題1で作成したInfoBeanを使用し、以下の情報をListに追加してください。
名前 | 住所 | 仕事 | 年齢 |
---|---|---|---|
佐藤 | 東京都練馬区 | Javaプログラマ | 19 |
伊藤 | 東京都千代田区 | PHPプログラマ | 30 |
鈴木 | 東京都墨田区 | Javaプログラマ | 25 |
山崎 | 東京都千代田区 | Javaプログラマ | 20 |
Listに追加後、以下のようにコンソールに追加した情報を全て出力してください。
佐藤 東京都練馬区 Javaプログラマ 19
伊藤 東京都千代田区 PHPプログラマ 30
鈴木 東京都墨田区 Javaプログラマ 25
山崎 東京都千代田区 Javaプログラマ 20
import java.util.ArrayList;
import java.util.List;
public class BeanMondai1_2 {
public static void main(String[] args) {
// 個人情報を保持するリストオブジェクト
List<InfoBean> beanList = new ArrayList<InfoBean>();
// 佐藤さんの情報を格納するBeanオブジェクトを作成
InfoBean bean1 = new InfoBean();
bean1.setName("佐藤");
bean1.setAddress("東京都練馬区");
bean1.setJob("Javaプログラマ");
bean1.setAge(19);
// 佐藤さんの個人情報を格納したBeanオブジェクトをリストオブジェクトに追加
beanList.add(bean1);
// 伊藤さんの情報を格納するBeanオブジェクトを作成
InfoBean bean2 = new InfoBean();
bean2.setName("伊藤");
bean2.setAddress("東京都千代田区");
bean2.setJob("PHPプログラマ");
bean2.setAge(30);
// 伊藤さんの個人情報を格納したBeanオブジェクトをリストオブジェクトに追加
beanList.add(bean2);
// 鈴木さんの情報を格納するBeanオブジェクトを作成
InfoBean bean3 = new InfoBean();
bean3.setName("鈴木");
bean3.setAddress("東京都墨田区");
bean3.setJob("Javaプログラマ");
bean3.setAge(25);
// 鈴木さんの個人情報を格納したBeanオブジェクトをリストオブジェクトに追加
beanList.add(bean3);
// 山崎さんの情報を格納するBeanオブジェクトを作成
InfoBean bean4 = new InfoBean();
bean4.setName("山崎");
bean4.setAddress("東京都千代田区");
bean4.setJob("Javaプログラマ");
bean4.setAge(20);
// 山崎さんの個人情報を格納したBeanオブジェクトをリストオブジェクトに追加
beanList.add(bean4);
// 各個人情報をコンソールに出力
for (InfoBean bean : beanList) {
System.out.println(bean.getName() + "\t" + bean.getAddress()
+ "\t" + bean.getJob() + "\t" + bean.getAge());
}
}
}
まず最初に個人情報を保持するInfoBeanクラスのオブジェクトを複数格納するためのリストを生成しましょう。
List<InfoBean> beanList = new ArrayList<InfoBean>();
リストオブジェクトを生成後、「佐藤」「伊藤」「鈴木」「山崎」の4名用にInfoBeanクラスのオブジェクトをそれぞれ生成し、setterメソッドを使用して個人情報を設定します。
InfoBeanクラスのオブジェクトに値を設定した後、InfoBeanオブジェクトをリストに格納します。
beanList.add(bean1);
リストに格納した後、拡張for文で各要素を取得し、コンソールに出力します。
各個人の情報を「\t」エスケープシーケンスで区切って出力しましょう。
練習問題1を参考に、今度は、ファイルから文字列を読み込む処理を加えたプログラムを作成しましょう。
事前準備として以下の内容の「mondaibean.txt」を作成し、「C:\temp」に保存してください。
佐藤,東京都練馬区,Javaプログラマ,19
伊藤,東京都千代田区,PHPプログラマ,30
鈴木,東京都墨田区,Javaプログラマ,25
山崎,東京都千代田区,Javaプログラマ,20
事前準備で作成したファイルを読み込み、練習問題1で作成したInfoBeanに格納してください。
格納する際は、Stringクラスのsplitメソッドを使用してカンマで分割できます。
Beanに格納したら読み込んだ情報をListに追加し、以下のようにコンソールの出力を行ってください。
佐藤 東京都練馬区 Javaプログラマ 19
伊藤 東京都千代田区 PHPプログラマ 30
鈴木 東京都墨田区 Javaプログラマ 25
山崎 東京都千代田区 Javaプログラマ 20
※この問題の解答は掲載しておりません。Tech Fun ITスクールのJava研修では、講師が丁寧に解説しています。
問題1で作成したプログラムを実行した結果、以下のようにコンソール出力するよう、InfoBeanを修正してください。
ただし、InfoBeanのnameに格納されている値を変更してはいけません。
佐藤(PG) 東京都練馬区 Javaプログラマ 19
伊藤(SE) 東京都千代田区 PHPプログラマ 30
鈴木(SE) 東京都墨田区 Javaプログラマ 25
山崎(PG) 東京都千代田区 Javaプログラマ 20
※この問題の解答は掲載しておりません。Tech Fun ITスクールのJava研修では、講師が丁寧に解説しています。
本章の内容も実務で当然のように使われています。
練習問題を繰り返し解いて、スムーズに扱えるようになっておきましょう。
JavaBeansについての説明は、以上です。