質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

サーブレット

サーブレット(Servlets)とはウェブやアプリケーションサーバー上に動くプログラムのことであり、ウェブブラウザや他のHTTPクライエントとデータベースやHTTPサーバー上のアプリケーションの中間層としての働きをします。

Q&A

3回答

1056閲覧

Javaにおけるインスタンス生成の質問

betelgeuse931

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

サーブレット

サーブレット(Servlets)とはウェブやアプリケーションサーバー上に動くプログラムのことであり、ウェブブラウザや他のHTTPクライエントとデータベースやHTTPサーバー上のアプリケーションの中間層としての働きをします。

0グッド

0クリップ

投稿2021/06/17 00:38

Javaでシステムを構築しています。
その際に疑問に思ったことがあります。

public List<MemberBean> selectMember(MemberBean member) throws SQLException, ClassNotFoundException {

List<MemberBean> memberList = new ArrayList<MemberBean>(); String sql = "SELECT * FROM m_member INNER JOIN m_area ON m_member.area_id = m_area.area_id WHERE age " + "BETWEEN ? AND ? AND hairstyle_id = ? AND m_member.area_id = ? AND delete_flag = 0"; try (Connection con = ConnectionManager.getConnection(); PreparedStatement pstmt = con.prepareStatement(sql)) { pstmt.setInt(1, member.getMinAge()); pstmt.setInt(2, member.getMaxAge()); pstmt.setInt(3, member.getHairStyleId()); pstmt.setInt(4, member.getAreaId()); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { MemberBean memberB = new MemberBean(); memberB.setName(rs.getString("name")); memberB.setAge(rs.getInt("age")); memberB.setArea(rs.getString("area")); memberB.setPhoto(rs.getString("photo")); memberList.add(memberB); } } return memberList; }

こちらのwhile文直下のインスタンス生成について聞きたいです。
while内でbeanをインスタンス生成するとうまくいくのはわかります。

しかし、while文外でインスタンス生成するとテーブルの中に入っている最後の情報にすべてコピーされてしまいます。その理由とはどのようなものなのでしょうか。

(例)
MemberBean memberB = new MemberBean();

while (rs.next()) {

memberB.setName(rs.getString("name")); memberB.setAge(rs.getInt("age")); memberB.setArea(rs.getString("area")); memberB.setPhoto(rs.getString("photo")); memberList.add(memberB); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/06/17 00:48

コードはマークダウンのcodeにてご提示ください
guest

回答3

0

ここで、while文の外でインスタンスを生成したときは、memberListの中身が全て最後のレコードの情報になってしまうからです。

while文の外でインスタンスを生成したときも、while文でレコードを1件ずつ取得して、memberList.add(memberB);で、そのレコードの情報をmemberListに追加しているとお思いなのだと思うのですが、実は違っています。

memberList.add(memberB);で渡しているのは、memberBというインスタンスの中身ではなくて、参照(ショートカットのようなもの)です。

例えばテーブルのレコードが5件あるとします。
while文の外でインスタンスを生成した場合、memberBという(1つの)インスタンスの中身を5回更新して、memberBに入っているのは、最終的には最後のレコードの情報になります。
そして、memberListには、最後のレコードの情報が入ったインスタンスへの参照(ショートカット)が5件入っているわけです。

一方、while文の中でインスタンスを生成するときは、同じmemberBという名前ではありますが、インスタンスが5件出来るので、問題ない、ということです。

投稿2021/06/17 00:53

編集2021/06/17 00:58
hallen0225

総合スコア587

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

仮に順序を変えて・・・

java

1MemberBean memberB = new MemberBean(); 2 3while (rs.next()) { 4 memberList.add(memberB); 5 6 memberB.setName(rs.getString("name")); 7 memberB.setAge(rs.getInt("age")); 8 memberB.setArea(rs.getString("area")); 9 memberB.setPhoto(rs.getString("photo")); 10} 11

とした場合にListの1件目のmemberBには、値がセットされないnew した直後のデータと考えていますか?

同じインスタンスを複数回追加しているので、インスタンスへの変更はすべてに反映されます。
※addした時点でインスタンスのコピーが作られるわけではありません

以下の2つのコードは同じ内容を出力します。

java

1StringBuilder sb = new StringBuilder(); 2List<StringBuilder> sbList = new ArrayList<>(); 3 4sb.append("1"); 5sbList.add(sb); 6 7sb.append("2"); 8sbList.add(sb); 9 10sb.append("3"); 11sbList.add(sb); 12 13sb.append("4"); 14sbList.add(sb); 15 16for(var s : sbList) { 17 System.out.println(s); 18} 19

java

1StringBuilder sb = new StringBuilder(); 2List<StringBuilder> sbList = new ArrayList<>(); 3 4sbList.add(sb); 5sbList.add(sb); 6sbList.add(sb); 7sbList.add(sb); 8 9sb.append("1"); 10sb.append("2"); 11sb.append("3"); 12sb.append("4"); 13 14for(var s : sbList) { 15 System.out.println(s); 16} 17

投稿2021/06/17 02:09

momon-ga

総合スコア4820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

whileを抜けた後のmemberList内のイメージとしてはこんな感じです。

whileの外で1度だけインスタンスを生成した場合

memberList {memberB, memberB, memberB, memberB ...}

whileの中でインスタンスを生成した場合

memberList {memberB, memberB', memberB'', memberB''', ...}

whileの外で生成した場合、memberBを上書きし続ける為、
最終的には最後に取得した情報で埋まる訳です。

投稿2021/06/17 00:59

Luice

総合スコア766

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問