
No.7ベストアンサー
- 回答日時:
> あと補足なんですがインスタンスが確保されているものに
> a = null;とかするのは問題あるでしょうか?
> なんとなくメモリリークが起きる気がするのですが、、
問題ありません。メモリリークも起きません。
確かに、文字列を連結したりするたびに新しい文字列のインスタンスが生成されていきますが、Javaでは、不要になったインスタンスのメモリは、自動的に「ガーベジコレクタ」によって開放されます。
つまり、不要なインスタンスを破棄・処分するためのコードをいちいちプログラマが書く必要は無いのです。
ある変数に代入されているインスタンスが不要になったら、その変数にnullを代入しておくだけで、あとは適当なタイミングにガーベジコレクタがメモリを開放してくれます。(メモリの開放はnull代入の直後とは限りません)
No.6
- 回答日時:
(1)
String a;
a = "aaa";
(2)
String a = new String();
a = "aaa";
(1)と(2)の動作の違いについて。
(1)
String型の参照を格納する変数aを宣言。(つまりStringオブジェクトはまだ生成されていない。)
aに"aaa"というStringオブジェクトの参照を代入する。
メモリでいうならば「参照用のa」「"aaa"という内容のStringオブジェクト」の分だけ確保されます。
(2)
String型の参照を格納する変数aを宣言し、そのaに新しく生成(new)したStringオブジェクトの参照を代入する。
aに"aaa"というStringオブジェクトの参照を代入する。(これはaの参照先を"aaa"に書き換えただけで、上でnewしたStringオブジェクトに文字列"aaa"を代入したわけではありません。)
メモリでいうならば「参照用のa」「newしたStringオブジェクト」「"aaa"という内容のStringオブジェクト」の分だけ確保されます。
Stringであろうとオブジェクトは全て例外なく参照渡しです。Javaでは配列はオブジェクトなので配列も参照渡しです。このことを利用したのが#1さんの
>ちょっとずるいですが、
>要素数1の配列にすればできます。
です。
>Stringというのは特別なクラスなのでしょうか?
Java内部の仕様に組み込まれた特別なクラスですが、プログラマはいちいちそのことを意識しなくてもいいと思います。
意識しなければならないのは、String同士を連結して代入する際、新しいオブジェクトが生成されるという点です。(#4参照)
このことを知らないと今回のteststrのように文字列の「内容」を別のメソッドで書き換えたつもりが、実は書き換わっていない、というバグに繋がる可能性があります。
「頻繁に内容が変更される文字列」を扱うのでしたらStringBufferを使用することをお勧めします。=や+での操作はできなくなりますが、メモリやパフォーマンスの面でStringBufferの方が上回ります。Stringは「固定長の文字列」を扱うのに便利なクラスであると心得てください。
No.5
- 回答日時:
プリミティブ型でもオブジェクト型でも、変数を宣言しただけでは、まだ実体は存在しないことに注意してください。
変数の中に実体が存在するのは、代入を行ってからです。(ただし、オブジェクト型変数にnullを代入した場合は、実体は実質的に存在しないことになりますが)
> Cのポインタ渡しとは違うのでしょうか
「参照渡し」は、「ポインタ渡し」と同じことです。ただ、Javaではポインタとは言わずに参照という言葉を使うのです。
> String a = new String();とString a;
> ではメモリ管理が変わるのでしょうか
メモリ管理が異なるというより、処理の内容全体が異なります。
String a;
というのは、変数を宣言しただけです。
まだ代入していないので、変数の中身を取り出すことはできません。(この点C言語とは若干異なります)
String a = new String();
では、大きく分けて三つの処理が行われます。
一つ目は、上と同じく、変数領域の確保です。
二つ目は、新しいStringのインスタンス(実体)の生成です。
三つ目は、生成した文字列インスタンスを代入することです。(厳密には、代入されるのはインスタンスそのものではなくてインスタンスへの参照です)
上と異なる点は、代入《までも》行われる点です。つまり、このあと変数の中身を取り出すことができます。
最後に、
a = a + "bbb";
についてですが、これは、
「二つの文字列をつなげて、新しい文字列インスタンスを作り、それを代入する」
ということが行われます。
(厳密な処理内容は、4番目の回答でSephyさんがおっしゃっている通りですが)
注意する点は、もともと変数aに入っていた文字列インスタンスの中身が書き換えられるのではなく、まったく新しい文字列インスタンスが生成してそれが代入されるという点です。
> 関数teststrのString aの実体はコピーが渡されるているのでしょうか
(Stringはオブジェクト型なので)渡されるのはあくまでも参照です。そして、変数の中身も参照です。
ただし、teststrメソッドの中で、
a = a + "bbb";
としても、これはteststrメソッドの中で使われている変数aに文字列を代入し直しただけです。
つまり、teststrメソッドの変数aの中身は、"aaa"への参照から"aaabbb"への参照に代わりますが(もちろんこの二つの文字列は別なインスタンスです)、mainメソッドの変数aの中身は、aaa"への参照が代入されたままだということです。
>String a; というのは、変数を宣言しただけです。
>まだ代入していないので、変数の中身を取り出すことはできません。(この点C言語とは若干異なります)
確かにString aの時点ではnull状態ですね。
a = "aaa";をはじめて実行したときにインスタンスが確保されるということですね?
あと補足なんですがインスタンスが確保されているものに
a = null;とかするのは問題あるでしょうか?
なんとなくメモリリークが起きる気がするのですが、、
No.4
- 回答日時:
teststrメソッド内の
a = a + "bbb";
のところで混乱しているのだと思います。
Stringの代入
a = a + "bbb";
は、コンパイラによって
a = new StringBuffer().append(a).append("bbb").toString();
のように書き換えられます。ここで新しくStringBufferがnewされていることに注目してください。
ご回答ありがとうございます。大変参考になりました。
コンパイラが値渡しであるかのように見せかけているのですね?
Stringというのは特別なクラスなのでしょうか?
或いは他にも、StringとStringBufferの関係のクラスってあるのでしょうか?
No.3
- 回答日時:
intやfloatなどはプリミティブタイプですのでその値が直接格納されます。
引数渡しにおいては値のコピーが渡されることになります。
そして、Stringはクラスですので引数渡しは参照渡しになります。
しかしStringはデータを変更できません。
String str="Hello";
str+=" world";
とした場合には、まず最初に「Hello」というデータもつStringオブジェクトを
strが参照することになります。
しかし、その後「world」という文字列を追加しようとしても、もとのオブジェクトとは別の
「Hello world」というデータをもつオブジェクトを参照することになります。
よって「一応」参照渡しとなっていますが呼び出し元のオブジェクトを書き換えることが出来ません。
(値を見ることは出来ますが)
文字データを参照で扱う場合にはStringBufferクラスを使います。
プリミティブタイプを参照で扱うためにはIntegerクラスやDoubleクラスなどがあります。
この回答への補足
import java.util.Vector;
class test{
public static void main(String[] args) throws NumberFormatException,IOException{
String a;
a = "aaa";
System.out.println(a);
teststr(a);
System.out.println(a);
return;
}
public static void teststr(String a){
a = a + "bbb";
System.out.println(a);
}
}
ちょっと混乱してきました。
これは参照渡しですよね?
先ほどのプログラムを
String a = new String();
に書き換えると、最後のaaaが表示されなくなりました。
ただのString a;でも実体はありますよね?
String a = new String();とString a;
ではメモリ管理が変わるのでしょうか?
ご回答ありがとうございます。
例えば下記この場合
関数teststrのString aの実体はコピーが渡されるているのでしょうか?
class test{
public static void main(String[] args) throws NumberFormatException,IOException{
String a;
a = "aaa";
System.out.println(a);
teststr(a);
System.out.println(a);
return;
}
public static void teststr(String a){
a = a + "bbb";
System.out.println(a);
}
}
No.2
- 回答日時:
intやdoubleなどの値型は必ず値渡しです。
Stringや配列などのオブジェクト型は必ず参照渡しです。
> 関数にStringを渡したとき内部的に自分のコピーを作っているということなのでしょうか
そのようなことはありません。メソッド(Javaでは関数とは呼びません)に文字列を渡しても、インスタンスが勝手にコピーされるということはありません。なぜなら、参照渡しだからです。
見た目が値渡しであるかのように見えるのは、文字列のインスタンスの内容を書き換えられないからです。
ご回答ありがとうございます。ひょっとすると私が「参照渡し」という言葉の定義を勘違いしているのかもしれません。
Cのポインタ渡しとは違うのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
先着1,000名様に1,000円分もらえる!
教えて!gooから感謝をこめて電子書籍1,000円分プレゼント
-
javaでは基本型の参照渡しは無理ですか?
Java
-
String型の日付(2005/11/25)の比較
Java
-
データベースのINT型項目にNULLはNG?
MySQL
-
4
Path型をString型へ変換する(Java)
Java
-
5
StringBufferからStringへキャストする
Java
-
6
Javaでポインタ的なことはできるか?
Java
-
7
JSPのNULLレコード表示について教えて下さい。
Java
-
8
jspからjavascriptの変数引継ぎ
JavaScript
-
9
Eclipseのアンインストールの仕方
Java
-
10
Javascriptの値をJava(JSP)へ渡す方法
Java
-
11
【DB】同じトランザクション内でupdateとselectをしたときの結果値
その他(データベース)
-
12
Oracleのデータ型、NUMBERについて
その他(データベース)
-
13
JSPの処理の途中で、JavaScriptの処理をしたい
JavaScript
-
14
時間帯判定をする。
Java
-
15
windows 環境でのファイル操作について
Java
-
16
Excelで、空白を表示したい
Excel(エクセル)
-
17
count(1)とcount(*)の違い
Oracle
-
18
テーブルタグの中にdivを含めてはダメ?
HTML・CSS
-
19
Excelで指数表現しないようにする方法
Excel(エクセル)
-
20
JAVAでCの関数ポインタのようなことをするには?
Java
関連するQ&A
- 1 javaについて教えてください。java初心者です。int arr[] = new int[
- 2 String(byte[] bytes, int offset, int length)の文字コードは?
- 3 Javaの参照渡し
- 4 javaの参照渡しの問題
- 5 javaでは基本型の参照渡しは無理ですか?
- 6 JAVAでの、clone() 参照渡し?について
- 7 JAVAの質問です。 ( String args[] )それとも(String[] args) ?
- 8 【javascript 文法】値渡し?参照渡し?
- 9 プリミティブ以外のデータ型が分からないので教えて
- 10 分を表す数値(int型)を、String型の"○時間○分"形式に直したい
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
人気Q&Aランキング
-
4
インスタンス参照でアクセスで...
-
5
「インスタンス」の意味をわか...
-
6
文字列を日付に変換でParseExce...
-
7
SQLを連続発行する時の正しい(?...
-
8
C#において、同じインスタンス...
-
9
private static という変数の修飾
-
10
Servletにおけるスレッド間での...
-
11
C#デストラクタが走る理由がわ...
-
12
変数の参照でエラーが出てしま...
-
13
C#でオブジェクトの有無を取得する
-
14
C#のメモリ解放についてご教授...
-
15
VB.NET getとsetの概念がわかり...
-
16
vb.netでFAXを送信する方法
-
17
ファイル読み込み/書き込み速度...
-
18
Javaを勉強し始めました。クラ...
-
19
Form1上にあるTextBox1を Modul...
-
20
シングルトン内で使用したオブ...
おすすめ情報