mutable class

通常クラスはmutable class(可変)である。
クラス内部のフィールドが参照型になっていて値を変更できる。
AクラスのインナークラスBがある。
Bが変更可能だとする。
Aクラスのインスタンスを2つ作り(a1,a2)、それぞれのBに同じインスタンス(b1)をセットする。このときa1.B, a2.Bは同じインスタンスを指している。
a1から取り出したB(b1)の値を変更するとa2の中身のB(b1)の値も変更されている。

```java
class B{
    int i;
    B(int i){
        this.i = i;
    }
}
class A{
    B b;
    A(B b) {
        this.b = b;
    }
    void setB(B b) {
        this.b = b;
    }
    B getB() {
        return this.b;
    }
}
public class SampleProject {
    public static void main(String[] args) {
        B b1 = new B(1);
        B b2 = new B(2);
        A a1 = new A(b1);
        A a2 = new A(b1);
        printA("a1",a1);
        printA("a2",a2);
        a1.getB().i = 100;
        printA("a1",a1);
        printA("a2",a2);
    }
    static void printA(String varName, A a) {
        method(varName,a);
        B b = a.getB();
        method("a.getB()", b);
        System.out.println(b.i);
    } 
    static void method(String varName, Object o) {
        System.out.println(varName + " identityHashCode:" + System.identityHashCode(o) + " " + o.toString());
        System.out.println(varName + " HashCode:" + o.hashCode() + " " + o.toString());
    }
}
```
```
a1 identityHashCode:1449621165 sampleproject.A@566776ad
a1 HashCode:1449621165 sampleproject.A@566776ad
a.getB() identityHashCode:167185492 sampleproject.B@9f70c54
a.getB() HashCode:167185492 sampleproject.B@9f70c54
1
a2 identityHashCode:592179046 sampleproject.A@234bef66
a2 HashCode:592179046 sampleproject.A@234bef66
a.getB() identityHashCode:167185492 sampleproject.B@9f70c54  //a1.Bとa2.Bが同じインスタンス
a.getB() HashCode:167185492 sampleproject.B@9f70c54
1
a1 identityHashCode:1449621165 sampleproject.A@566776ad
a1 HashCode:1449621165 sampleproject.A@566776ad
a.getB() identityHashCode:167185492 sampleproject.B@9f70c54   
a.getB() HashCode:167185492 sampleproject.B@9f70c54
100
a2 identityHashCode:592179046 sampleproject.A@234bef66
a2 HashCode:592179046 sampleproject.A@234bef66
a.getB() identityHashCode:167185492 sampleproject.B@9f70c54
a.getB() HashCode:167185492 sampleproject.B@9f70c54
100      //a1.Bを100にした影響でa2.Bも100になった
```
mutableなクラスは内部的にshallow copyので、あるクラスのフィールド変更が
ほかのクラスのフィールド変更になる。
スレッド処理の場合に正しい結果とならない可能性がある。
shallow copyからdeep copyとすることにより、必ず別のインスタンスで処理
されるようになり、この問題が解決される
・constructor, setterは、newした値をセットすることによりdeep copyとなる
・getterは、newした値を返すことによりクラス内部の値に影響を受けない
```java
interface SampleInterface {
    default void method(String varName) {
        System.out.println(varName + " identityHashCode:" + System.identityHashCode(this) + " " + this.toString());
        System.out.println(varName + " HashCode:" + this.hashCode() + " " + this.toString());
    }
}
class B implements SampleInterface {
    int i;
    B(int i){
        this.i = i;
    }
    @Override
    public void method(String varName) {
        SampleInterface.super.method(varName);
        System.out.println("B.i " + this.i);
    }
}
class A implements SampleInterface {
    B b;
    A(B b) {
        this.b = new B(b.i);
    }
    void setB(B b) {
        this.b = new B(b.i);
    }
    B getB() {
        return new B(this.b.i);
    }
    @Override
    public void method(String varName) {
        SampleInterface.super.method(varName);
        this.b.method(varName + ".B");
    }
}
public class SampleProject {
    public static void main(String[] args) {
        B b1 = new B(1);
        B b2 = new B(50);
        A a1 = new A(b1);
        A a2 = new A(b1);     //a1.B,a2.Bは別インスタンス
        a1.method("a1");
        a2.method("a2");
        a1.setB(b2);          //a2.Bに影響を与えない。construct時点で別インスタンスだけども念のため。。
        a1.method("a1");
        a2.method("a2");
        a1.getB().i = 99;     //a1.Bに影響を与えない。
        a1.method("a1");
        a2.method("a2");
    }
}
```
```
a1 identityHashCode:1627960023 sampleproject.A@6108b2d7
a1 HashCode:1627960023 sampleproject.A@6108b2d7
a1.B identityHashCode:863831416 sampleproject.B@337d0578
a1.B HashCode:863831416 sampleproject.B@337d0578
B.i 1
a2 identityHashCode:1702146597 sampleproject.A@6574b225
a2 HashCode:1702146597 sampleproject.A@6574b225
a2.B identityHashCode:644460953 sampleproject.B@2669b199   //a1.Bとidentityhashcodeが異なる。つまり別インスタンス
a2.B HashCode:644460953 sampleproject.B@2669b199
B.i 1
a1 identityHashCode:1627960023 sampleproject.A@6108b2d7
a1 HashCode:1627960023 sampleproject.A@6108b2d7
a1.B identityHashCode:591723622 sampleproject.B@2344fc66
a1.B HashCode:591723622 sampleproject.B@2344fc66
B.i 50
a2 identityHashCode:1702146597 sampleproject.A@6574b225
a2 HashCode:1702146597 sampleproject.A@6574b225
a2.B identityHashCode:644460953 sampleproject.B@2669b199    //a1.setB()はa2.Bに影響を与えていない
a2.B HashCode:644460953 sampleproject.B@2669b199
B.i 1
a1 identityHashCode:1627960023 sampleproject.A@6108b2d7
a1 HashCode:1627960023 sampleproject.A@6108b2d7
a1.B identityHashCode:591723622 sampleproject.B@2344fc66    //a1.getB().i = 99は、a1.Bに影響を与えていない
a1.B HashCode:591723622 sampleproject.B@2344fc66
B.i 50
a2 identityHashCode:1702146597 sampleproject.A@6574b225
a2 HashCode:1702146597 sampleproject.A@6574b225
a2.B identityHashCode:644460953 sampleproject.B@2669b199    //a2.Bはconstruct以降なにも影響を受けていない
a2.B HashCode:644460953 sampleproject.B@2669b199
B.i 1
```