きっかけ
findbugsをつかっていて、EI_EXPOSE_REP2 というのが、あって気になって調べてみました。
詳細
May expose internal representation by incorporating reference to mutable object
平たくいうと、内部で保持するためのデータを、外部からのmutableなものをそのまま使っているので、外から変更できてしまう、ということです。
よくある具体例は、配列やリストです。
public class Example1 {
private int[] numbers;
public Example1(int[] numbers) {
this.numbers = numbers;
}
public int[] getNumbers() {
return this.numbers;
}
}
int[] numbers = {1,2,3};
Example1 ex1 = new Example(numbers);
// コンストラクタにわたしものの中身を変更
numbers[0] = 10;
ex1.getNumbers();
// => {10,2,3}
上記のように、privateにして内部に隠蔽したつもりなのに、もとがmutableだとこのように外から中身を変えられてしまいます。Listでも同様のことができ、#clear()をつかってしまうと外から中身を空にすることも... Java7までならDateもこれにあたります。
解決策
Object指向的に好ましくないということで、findbugsで警告がでてきます。回避策もでていて、
- cloneしたものをわたす
- immutableなものにかえる
の2つです。ごもっともですねw
Javaでimmutableとなると、Guavaなどのライブラリをつかうのが手っ取り早いかと。
所感
コンストラクタやsetterの引数がmutableかどうかは気をつけないとですね。
こういう風に、バグの原因になりそうなものや、悪いパターンを気づきやすくなるのでfindbugsはありがたいです。経験が浅いメンバーがいるプロジェクトほど、こういったものがあるとよいのですが。
参考サイト