• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:JAVAアソシエイツの問題)

JAVAアソシエイツの問題について

このQ&Aのポイント
  • JAVAアソシエイツの問題「SUN教科書 JAVAアソシエイツ P209 問5-7」からの問題についてです。
  • 次のプログラムの空欄(1)に入れて実行すると、出力結果がtrueになるコードはどれですか。
  • 正解はADFGです。AFGに関しては理解出来るのですが、どうして選択肢Dがtrueなのに選択肢Eはfalseになるのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.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

taro_11
質問者

お礼

>>jjon-com様 詳細で丁寧な解説をありがとうございました。 番地を仮定する考え方はすごく分かりやすかったです。

その他の回答 (5)

  • Ogre7077
  • ベストアンサー率65% (170/258)
回答No.5

オブジェクト型同士の比較演算子とは 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 を使え!」です。

taro_11
質問者

補足

【重複になります。ご了承して頂ければ幸いです。】 返信ありがとうございます。 申し訳ありませんが理解出来ませんでした。 私なりの解釈を記述させて頂きます。 (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)
回答No.4

#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」を参照している などとは考えないはずです。

taro_11
質問者

補足

【重複になります。ご了承して頂ければ幸いです。】 返信ありがとうございます。 申し訳ありませんが理解出来ませんでした。 私なりの解釈を記述させて頂きます。 (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)
回答No.3
taro_11
質問者

補足

【重複になります。ご了承して頂ければ幸いです。】 返信ありがとうございます。 申し訳ありませんが理解出来ませんでした。 私なりの解釈を記述させて頂きます。 (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)
回答No.2

見落としがありました。 選択肢Aはtrue、 B,Cがfalseになるのは理解してるんですよね? それと同じ理由です。

taro_11
質問者

お礼

>>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)
回答No.1

==とString.equalsメソッドの違い sx="Hello"とsx=new String("Hello")の違い 理解できていますか? 参考書などに、必ず載っているような重要な事です。 同じ内容でも、==ではない、というのは、よくあることです。

taro_11
質問者

補足

選択肢DとEの違いについて解説して頂ければ助かります。

関連するQ&A