【JAVA】参照渡しと値渡し Part1

参照渡しとか、値渡しとか、いかにも”コンピュータ”という感じの
用語には鳥肌が立つほど苦手なてるですが、
この小難しい用語について一度整理をしてしっかりと脳みそに叩き込んでしまいたいと思います。

みなさんもしっかりとついてきてくださいね。

まずしっかりと覚えなければいけないのは
『参照渡し』『値渡し』という用語。

まず『参照渡し』。
これは、私が見ている場所にはこれがありますよ。ということ。
たとえば、机の上にリンゴがあります。
ここで他の人が机の上のリンゴをミカンに取り替えた場合。

『あなたが見ているのは何ですか?』という質問があったとき
見ているのは机の上なので、ミカンに変わってしまいます。


で、反対に値渡し。
これは、私が見ているものはこれですよ。ということ。
先ほどの例にたとえると、机の上にリンゴがあります。
でも、見ているのはリンゴ。
ここで他の人が机の上のリンゴをミカンに取り替えた場合。

『あなたが見ているのは何ですか?』という質問があったとき
ずっとリンゴを見ているので答えは『リンゴ』ですね。


つまり、同じ質問が来ても、何(どこ)を見ているのかで答えが変わります。

実際には"渡し"という言葉のとおり他の人がいきなり取り替えるではなく、
他の人にリンゴの管理を任せた(渡した)後、"机"に注目するのか、"リンゴ"に注目するのかということです。
ただ、おそらくこの例えのほうがわかりやすいかと思います。



で、Java の場合、どうなるかといえば。


一般的に引数であれば、プリミティブ型(booleanとかintとか)であれば値渡し、
オブジェクト(BeanやMap)であれば参照渡しといわれています。

でも、これが誤解を生む原因となっています。

なので、余計にわかりづらい。
ここでしっかりと整理し、すっきりしちゃいましょう。


さて、下記のようなソースがあった場合、コンソールに出力される値は何でしょうか?


public class Sample {

    public static void main(String[] args){
        int value = 0;
        test1(value);
        System.out.println(value);
    }

    public static void test1(int id) {
        id = 1;
    }
}



実際に試していただきたいのですが答えは、『0』です。
『プリミティブ型(booleanとかintとか)であれば値渡し』のとおり、
私が見ているのは0だ!他人が机の上を変えようが0だ! ということです。

では、下のソースでは??


public class Sample {

    public static void main(String[] args){
        String value = "テスト";
        test1(value);
        System.out.println(value);
    }

    public static void test1(String id) {
        id = "ほげほげ";
    }
}



答えは、次回に。
スッキリしてもらうために少しの間モヤモヤしていてください。
(気になる方は自身で試してみてくださいね。)



参考になりましたらクリックしていただけると励みになります。



【JAVA】参照渡しと値渡し Part2

前回の記事からだいぶ時間がたってしまいました。。。
すいません。


さて、続きのお話です。


前回の宿題の答えですが、
『テスト』と出力されるのが正解です。


むむむ??

Stringはオブジェクトなので参照渡し。
つまり、机の上のリンゴをミカンに取り替えたということになり
『ほげほげ』が出力されるのでは??
と考えてしまいがちです。




では、なぜなのかそうなるのか?


一見机の上のリンゴをミカンに取り替えたように思ってしまうのですが、
実は机ごと変わってしまっているのです。

つまり、

山田君の机の上にリンゴがあります。
佐藤さんの机の上にはミカンがあります。

席替えがあり山田君の机の位置に佐藤さんの机が移動になりました。

では、山田君の机の上には何がありますか?

そう。『リンゴ』です。


つまり、前回の例では上のような操作が行われているのです。


厳密に言うと参照渡しはこういう意味です。

山田君の机の上にリンゴがあります。
山田君の机の上のリンゴをミカンに取り替えます。

では、山田君の机の上には何がありますか?


JAVAの用語を使うとどういう意味となるかというと
『オブジェクト(山田君の机)の状態(机の上にあるもの)が変わるとき』




コードで書くとこんな感じです。



public class Sample {

    public static void main(String[] args){
        Bean bean = new Bean();
        bean.setValue("テスト");
        test1(bean);
        System.out.println(bean.getValue());
    }

    public static void test1(Bean bean) {
        bean.setValue("ほげほげ");
    }
}

class Bean {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}




結論を言うと、参照渡し、値渡しという意味は上のようになりますが
不具合を埋め込まずコーディングするという目的を果たすためには
厳密に意味を理解するよりはオブジェクトの状態(持っているもの)を変えてしまうと
影響があるんだ程度に覚えておけばよろしいかと。




参考になりましたらクリックしていただけると励みになります。



【JAVA】nullでもインスタンスでも無い状態!?

今回の記事は少し難しいかもしれません。
その上、結構マニアックな話です。覚悟してください(笑)

会社の上司や先輩などにデザインパターンを習えといわれたことはありませんか?

デザインパターンの中にシングルトンパターンというものがあります。

今日はシングルトンパターンというもののTIPS的なお話をしたいと思います。
もし、シングルトンパターンというのを知らない方は上のリンクを参照してみてください。
簡単に言うと1つしかないという意味です

参考書などを見るとシングルトンパターンの例が下のように記載されていることがあります。
でも、実はこれ厳密にいうと間違いなのです。

さて、どこが間違えているかわかりますか??


private static Singleton instance;

public static Singleton getInstance() {
  if (instance == null) {
    synchronized(Singleton.class) {
      if (instance == null) {
        instance = new Singleton();
      }
    }
  }
  return instance;
}

まずは、上のソースの解説をしたいと思います。

4行目でSingletonのインスタンスが生成されているかを確認します。

5行目では、インスタンスが未作成の場合、他のスレッドからSingletonの
インスタンスを生成されないようロックをかけています。

6行目では、もう一度インスタンスが作られていないかを確認しています。
これは、4行目の条件判断の最中に別のスレッドでインスタンスを作成されていないということを確認するためです。

7行目の処理は、ロックもしているし、他のスレッドからインスタンスが作成されていないので
安心して自分が代表者になって唯一のインスタンスを生成!

という考えの基に書かれたコーディングです。


理論上正しいように思えるのですが、実際は違います。


なんと、nullでもなくインスタンスでも無い状態がJAVAにはあるのです。

すごく簡単に説明すると

1.instanceはnullである。
2.instanceをnullからインスタンスへ書き換えるため「null」という状態をはずす。
3.instanceはインスタンスですよとあらためて登録する。

ということをしているのです。

つまり、別のスレッドが2の状態で6行目のif文を通過し、
インスタンスを生成してしまうことがありえるのです。


では、シングルトンパターンは実際には実装できないのでしょうか?

気になるかたは、下記のリンクを参照してみてください。
もっと詳しく書かれています。
http://www.ibm.com/developerworks/jp/java/library/j-dcl/



参考になりましたらクリックしていただけると励みになります。



×

この広告は180日以上新しい記事の投稿がないブログに表示されております。