文系seの備忘録

Excelの改行でひたすらスペースを打っていた機械音痴の文系seが日々の備忘録を綴る。

メソッド引数がString型のときの挙動について

・背景、目的
「String型を引数として渡すメソッドを作る際には注意してね」と前作業でよく言われた。なんでなのかハッキリ調べないまま今になってしまった・・・。
最近勉強していて「String型変数は値の変更ができない」ということを知った。
でも、、なんで参照型なのにそんな動きになるの??なんで値が変更されないの???と気になったので調べてみた。




― 試しにコードをかいてみる。。。
 ①String型を引数にとるメソッドを作成する。
引数に任意の文字列を付加して引数に代入する。
 ②呼び出し元でString型変数に任意の文字列を設定しておき、それを作成したメソッドに渡す。
 ③呼び出し元のString型変数の値をチェックする。






②、③ 呼び出し元は以下。




String型は参照型なので、引数として渡されるのは文字列そのものでなく参照情報。
参照なら呼び出し先での処理が呼び出し元にも反映されそうだが、、↑ではそうなっていない。

⇒ Stringはimmutableなオブジェクトであり、生成後に文字列を変えることはできない。

testString = testString + "メソッド内で付加した文字列";

これは、右辺のtestString「渡す文字列」に、「メソッド内で~~」を付加した新たな文字列を生成し、
その文字列に対する参照情報を左辺のtestStringに代入している。
よって、呼び出し元と呼び出し先のtestStringは違う文字列となり、上のような結果となった。



・immutable
StringやDateなど。属性値が変更されない。
これが、参照型なのに値渡しされてるように見える理由。
引数として受け取ったオブジェクトから値を取り出して、それをもとに新しいオブジェクトを生成することを「防衛的コピー」という。


・まとめ
つまり、、、
String型の引数を渡す際にも、他の参照渡しの引数と同様にポインタの値が渡される。
でも、Stringがimmutableだから文字列加工の際には新たなオブジェクトになるということ。
もし参照渡しをしたいならStringBufferかStringBuilderを使う。
例)StringBuilder


さっきと同様に呼び出してみる



 ※ StringBufferクラスのすべてのメソッドはsynchronized(同期化)になっているので複数スレッド(
複数の端末から操作)から使用されても安全に使うことができる。StringBuilderは同期化されていないので、もし他のスレッドから同じオブジェクトが呼び出されたときに値が取られてしまう可能性もある。
例えば、StringBufferでappendするとアクセス順にappendされるが、StringBuilderはどっちかしかされない。基本的にはStringBuilderを使えばOKっぽい


 ※  サーブレット
 サーバーサイドで動作する小さなアプリ部品。実行結果がクライアントに返される。
 .javaファイルをコンパイルして.classファイルを作り、実行する。
 サーブレットはマルチスレッドで呼ばれる。毎回毎回クラスをロードするのではなく、既にロードされた
 クラスがあり、そのクラスのインスタンスを共用できる(インスタンスを一度だけ作るということ。シ ングルトンという)。処理が速いというメリットがある。