- ベストアンサー
JAVAアソシエイツの問題について
- JAVAアソシエイツの問題「SUN教科書 JAVAアソシエイツ P209 問5-7」からの問題についてです。
- 次のプログラムの空欄(1)に入れて実行すると、出力結果がtrueになるコードはどれですか。
- 正解はADFGです。AFGに関しては理解出来るのですが、どうして選択肢Dがtrueなのに選択肢Eはfalseになるのでしょうか。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
> 実務においてこの問題はどの程度重要なのでしょうか? 非常に重要です。 Javaにおいて「参照」がイメージできなければ, 文字列,配列も,異なるクラスにおける代入も, Javaコーディング上の多くの概念を理解できないことになりますから。 ---------------- 1: class Sample{ 2: public static void main(String[] args){ 3: String s1 = "Hello"; 4: String s2 = "Hello"; 5: String s3 = new String("Hello"); 6: System.out.println( 【(1)】 ); 7: } 8: } ---------------- >(5)そして、Stringオブジェクトが作成される順番により、 オブジェクトが作成される順番は関係ないです。 「番地」というイメージで適当な数値を仮定してみればよいかと。 ・3行目の"Hello" ・4行目の"Hello" ・5行目の"Hello" ・6行目の【(1)】に登場する"Hello" …すべて同一文字列なので同一オブジェクトとして確保される。 (仮に)1000番地を先頭にしてその"Hello"が確保されたとすると, そのアドレスはすべて1000番地 ・new String("Hello") …1000番地に存在する"Hello"を複製元として,別番地を先頭に 新たな文字列を確保している。(仮に)2000番地とする。 3: String s1 = "Hello"; 4: String s2 = "Hello"; …参照変数s1とs2には「1000」が代入される。 5: String s3 = new String("Hello"); …参照変数s3には「2000」が代入される。 D. s1 == "Hello" …1000と1000を比較。結果はtrue E. s3 == "Hello" …2000と1000を比較。結果はfalse
その他の回答 (5)
- Ogre7077
- ベストアンサー率65% (170/258)
オブジェクト型同士の比較演算子とは x == y 両者が同じオブジェクトなら ture、オブジェクトの値は比較せず x.equals(y) 両者が同じ値なら ture、オブジェクト自体は比較せず ソース内に直書きされた文字列(リテラル文字列)は、 効率化のために同じ値のものは同じオブジェクトと見なされます。 ゆえに "Hello" と書かれた部分は、全部同じオブジェクトと考えてください。 なので、 選択肢A : s1 と s2 は同じオブジェクト、x==y なので ture 選択肢B : s1 と s3 は違うオブジェクト、x==y なので false 選択肢C : s2 と s3 は違うオブジェクト、x==y なので false 選択肢D : s1 と "Hello" は同じオブジェクト、x==y なので ture 選択肢E : s3 と "Hello" は違うオブジェクト、x==y なので false 選択肢F : s1 と s3 は同じ値、x.equals(y) なので ture 選択肢G : s2 と s3 は同じ値、x.equals(y) なので ture 長くなりましたが要は「文字列の比較は equals を使え!」です。
補足
【重複になります。ご了承して頂ければ幸いです。】 返信ありがとうございます。 申し訳ありませんが理解出来ませんでした。 私なりの解釈を記述させて頂きます。 (1)まず最初に「String s1 = "Hello";」により「Hello」が生成され、s1がそれを参照する。 (2)「String s2 = "Hello";」ではすでに「Hello」が存在してるので、新しくStringオブジェクトは 生成されず、s2もs1と同じ「Hello」を参照する。 (3)「String s3 = new String("Hello");」ではnew演算子を使って「Hello」を生成しているので、 s1とs2が参照しているStringオブジェクトとは別に新たに「Hello」を生成し、s3がそれを参照する。 (4)それゆえに選択肢Dはtrueとなります。 ここまでは合ってますでしょうか? (5)そして、Stringオブジェクトが作成される順番により、 「s1 == "Hello"」はまずtrueとなり、 s3はs1が参照しているHelloとは異なるオブジェクトを 指し示しているから「s3 == "Hello"」はfalseとなる。 上記のような考え方ではダメなのでしょうか? (ちなみに、実務においてこの問題はどの程度重要なのでしょうか?)
- kmee
- ベストアンサー率55% (1857/3366)
#3にある図も参考にしてください。 この解説の載っていないJavaの入門書は無いはずです。 その教科書にも載っているのでは? 「文字列リテラルは、Stringのオブジェクトで、同じ内容のリテラルは同じオブジェクトになる」 このルールは、理解できていますか? > (1)まず最初に「String s1 = "Hello";」により「Hello」が生成され、s1がそれを参照する ここで生成される、というよりは、s1は「すでに存在する"Hello"オブジェクト」を参照する、という感じです。 以下、"Hello"とある文字列リテラルはすべて、「すでに存在する"Hello"オブジェクト(の参照)」です。 ちょっと疑似コードっぽくすると、こんなイメージ class Sample{ static final String リテラルHello = "Hello"; public static void main(String[] args){ String s1 = リテラルHello ; String s2 = リテラルHello ; String s3 = new String(リテラルHello ); // "Hello"を新しく生成するのではない。リテラルHelloと同じ内容の新規オブジェクトを生成する。 System.out.println( 【(1)】 ); } } 選択肢は D. s1 == リテラルHello E. s3 == リテラルHello このイメージができてれば > s3も「Hello」を参照している などとは考えないはずです。
補足
【重複になります。ご了承して頂ければ幸いです。】 返信ありがとうございます。 申し訳ありませんが理解出来ませんでした。 私なりの解釈を記述させて頂きます。 (1)まず最初に「String s1 = "Hello";」により「Hello」が生成され、s1がそれを参照する。 (2)「String s2 = "Hello";」ではすでに「Hello」が存在してるので、新しくStringオブジェクトは 生成されず、s2もs1と同じ「Hello」を参照する。 (3)「String s3 = new String("Hello");」ではnew演算子を使って「Hello」を生成しているので、 s1とs2が参照しているStringオブジェクトとは別に新たに「Hello」を生成し、s3がそれを参照する。 (4)それゆえに選択肢Dはtrueとなります。 ここまでは合ってますでしょうか? (5)そして、Stringオブジェクトが作成される順番により、 「s1 == "Hello"」はまずtrueとなり、 s3はs1が参照しているHelloとは異なるオブジェクトを 指し示しているから「s3 == "Hello"」はfalseとなる。 上記のような考え方ではダメなのでしょうか? (ちなみに、実務においてこの問題はどの程度重要なのでしょうか?)
- jjon-com
- ベストアンサー率61% (1599/2592)
http://okwave.jp/qa/q8035503.html の私の回答No.4
補足
【重複になります。ご了承して頂ければ幸いです。】 返信ありがとうございます。 申し訳ありませんが理解出来ませんでした。 私なりの解釈を記述させて頂きます。 (1)まず最初に「String s1 = "Hello";」により「Hello」が生成され、s1がそれを参照する。 (2)「String s2 = "Hello";」ではすでに「Hello」が存在してるので、新しくStringオブジェクトは 生成されず、s2もs1と同じ「Hello」を参照する。 (3)「String s3 = new String("Hello");」ではnew演算子を使って「Hello」を生成しているので、 s1とs2が参照しているStringオブジェクトとは別に新たに「Hello」を生成し、s3がそれを参照する。 (4)それゆえに選択肢Dはtrueとなります。 ここまでは合ってますでしょうか? (5)そして、Stringオブジェクトが作成される順番により、 「s1 == "Hello"」はまずtrueとなり、 s3はs1が参照しているHelloとは異なるオブジェクトを 指し示しているから「s3 == "Hello"」はfalseとなる。 上記のような考え方ではダメなのでしょうか? (ちなみに、実務においてこの問題はどの程度重要なのでしょうか?)
- kmee
- ベストアンサー率55% (1857/3366)
見落としがありました。 選択肢Aはtrue、 B,Cがfalseになるのは理解してるんですよね? それと同じ理由です。
お礼
>>kmee様 返信ありがとうございます。 選択肢ABCDFGに関しては理解出来ております。 Sringオブジェクの生成される順序が、関係演算の判定に影響しているということなのでしょうか? 以下は私の考え方です。 (1)まず最初に「String s1 = "Hello";」により「Hello」が生成され、s1がそれを参照する。 (2)「String s2 = "Hello";」ではすでに「Hello」が存在してるので、新しくStringオブジェクトは 生成されず、s2もs1と同じ「Hello」を参照する。 (3)「String s3 = new String("Hello");」ではnew演算子を使って「Hello」を生成しているので、 s1とs2が参照しているStringオブジェクトとは別に新たに「Hello」を生成し、s3がそれを参照する。 (4)それゆえに選択肢Dはtrueとなります。 ここまでは合ってますでしょうか? まぎらわしいのはs3も「Hello」を参照しているので、 trueになり得るようにも解釈出来そうなのですが…。
- kmee
- ベストアンサー率55% (1857/3366)
==とString.equalsメソッドの違い sx="Hello"とsx=new String("Hello")の違い 理解できていますか? 参考書などに、必ず載っているような重要な事です。 同じ内容でも、==ではない、というのは、よくあることです。
補足
選択肢DとEの違いについて解説して頂ければ助かります。
お礼
>>jjon-com様 詳細で丁寧な解説をありがとうございました。 番地を仮定する考え方はすごく分かりやすかったです。