メモ・・・javaでBeanを作成する際、何も考えずgetterを作るとFindBugsで警告される話

前回はsetterについてお話を書いたので、今回はgetterに関して。

まずはBeanクラスについて。
これは前回setterについて書いたものを使用してみます。

package bean;

import java.util.Arrays;

public class HogeBean {

    private String[] hogeStrAr;

    public String[] getHogeStrAr() {
        return hogeStrAr;
    }

    public void setHogeStrAr(String[] hogeStrAr) {
        if(hogeStrAr == null){
            this.hogeStrAr = null;
        }else{
            this.hogeStrAr = (String[])hogeStrAr.clone();
        }
    }

    @Override
    public String toString() {
        return "HogeBean [hogeStrAr=" + Arrays.toString(hogeStrAr) + "]";
    }

}


この状態でFindBugsを使用すると、getterに以下のような警告メッセージが表示されます。

----------------------------------------------------------
Bug:
bean.HogeBean.getHogeStrAr() は HogeBean.hogeStrAr を戻すことにより内部表現を暴露してしまう可能性があります。
Pattern id: EI_EXPOSE_REP, type: EI, category: MALICIOUS_CODE

オブジェクトのフィールドに格納された変更可能なオブジェクトの参照を返すと、オブジェクトの内部表現を暴露してしまいます。もしも、このオブジェクトが信頼されていないコードによってアクセスされる事が、セキュリティや、その他の重要な情報への脅威となる可能性があるため、このコードは修正すべきです。防御的コピーを行って、複製を返すのが、多くの場面で良いやり方です。
---------------------------------------------------------

getterのどこがよろしくないのか検証するため、Beanを使用するクラスを以下のように作成しました。

package main;

import bean.HogeBean;

public class TestHoge {

    public static void main(String[] args) {

        String[] strAr = { "りんご", "みかん", "バナナ" };

        HogeBean hogeBean = new HogeBean();
        hogeBean.setHogeStrAr(strAr);

        // 現在のBeanの状態を確認
        System.out.println(hogeBean);

        //Beanの配列を取得してstrAr2に。
        String[] strAr2 = hogeBean.getHogeStrAr();

        //strAr2の0番目を変更してみる。
        strAr2[0] = "いちご";

        //Beanの状態を確認
        System.out.println(hogeBean);
    }

}


実行してみると
---------------------------------------------------------
HogeBean [hogeStrAr=[りんご, みかん, バナナ]]
HogeBean [hogeStrAr=[いちご, みかん, バナナ]]
---------------------------------------------------------
となりまして、getterで取得したものを変更すると、Beanの内容も変わってしまいます。

ですので、防御的コピーで対処しろってことなんですね。
setterのときと同様、ただ.cloneをつけるだけでは、nullが設定されている場合にNullPointerExceptionが発生してしまいます。
そのことを考慮して、以下のようにgetterを修正してみます。

    public String[] getHogeStrAr() {
        if (hogeStrAr == null) {
            return null;
        }
        return (String[]) hogeStrAr.clone();


そうすると、先ほどのTestHogeクラスを実行してみますと
---------------------------------------------------------
HogeBean [hogeStrAr=[りんご, みかん, バナナ]]
HogeBean [hogeStrAr=[りんご, みかん, バナナ]]
---------------------------------------------------------
となりまして、無事修正できました。
関連記事


--------------------------------------------------------------------------------------

コメントの投稿

非公開コメント

No title

とても魅力的な記事でした!!
また遊びに来ます!!
ありがとうございます。。

Re: No title

> とても魅力的な記事でした!!
> また遊びに来ます!!
> ありがとうございます。。

これって、魅力的な記事なのかな?
nullに関しての箇所は、Beanにデフォルト値を設定しておき、返す仕様でもいいかもしれませんし、
NullPointerExceptionが発生でも構わない仕様でもいいかと思います。
使う側の判断なんですよね。
このブログについて
  • 全記事一覧(時間順)
  • このブログについて
  • 私のプロフィール
  • 当ブログで扱っている動画について
  • 記事違いなコメントのお返事

  • カテゴリー
    twitter
    カレンダー
    09 | 2017/10 | 11
    1 2 3 4 5 6 7
    8 9 10 11 12 13 14
    15 16 17 18 19 20 21
    22 23 24 25 26 27 28
    29 30 31 - - - -
    Amazon
    でたらめな当ブログにぴったりな商品を自動で表示するみたいです。



    月別アーカイブ
    プロフィール

    たづみ

    Author:たづみ
    ・1981年生まれの男
    ・もう少し詳細なプロフィールはこちらで

    最新コメント
    アクセスランキング
    [ジャンルランキング]
    日記
    831位
    アクセスランキングを見る>>

    [サブジャンルランキング]
    会社員・OL
    176位
    アクセスランキングを見る>>