Javaのプログラムをコンソール上で実行した際に出てくる8桁の数とreturn文につきまして

今、このようなコードがあります。

-------------------------
package testprogramm;

class Tsukareta {
public String toString() {
return "どうしてもこの文字が?";
}
}
-------------------------

と、

-------------------------
package testprogramm;

class Equalityoperator {
public static void main(String[] args) {
Tsukareta mag1 = new Tsukareta();
Tsukareta mag2 = new Tsukareta();
System.out.println("mag1:" + mag1);
System.out.println("mag2:" + mag2);

System.out.println("mag1 == mag2->" + (mag1 == mag2));
System.out.println("mag1.equals(mag2)->" + mag1.equals(mag2));
}
}
-------------------------

の、2つのJavaファイルです。mainメソッドのあるEqualityoperatorクラスの方を実行すると、

-----------------------
mag1:どうしてもこの文字が?
mag2:どうしてもこの文字が?
mag1 == mag2->false
mag1.equals(mag2)->false
-----------------------

という結果が出力されます。

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2019/08/06 20:51:08
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。
id:moon-fondu

ここでTsukaretaクラスの方を、

-------------------------

package testprogramm;

class Tsukareta {

public String naze() {

return "どうしてもこの文字が?";

}

}

-------------------------

と、適当にnazeメソッドというものに変更してみます。(Eclipse上でエラーなくコンパイルできます)

その後、Equalityoperatorクラスのmainメソッドを実行すると、

-------------------------

mag1:testprogramm.Tsukareta@532760d8

mag2:testprogramm.Tsukareta@57fa26b7

mag1 == mag2->false

mag1.equals(mag2)->false

-------------------------

と、全く違う結果が出てくるのです。

「@532760d8」「@57fa26b7」の8桁の文字列は、おそらくJavaのメモリの領域を確保したときの領域を示す?ものだと思うのですが。

なぜtoStringメソッドを使ったときはreturn文の文字列が出てきて、その他のnaze等の変数を使ったメソッドでは8桁の文字列が出てきたのか、その理由が知りたいです。

調べても考えてもわからず疲れ果ててしまいまして…お力添えをいただけますと幸いです。

よろしくお願い致します。

ベストアンサー

id:a-kuma3 No.1

回答回数4974ベストアンサー獲得回数2154

ポイント600pt

System.out は、java.io.PrintStream というクラスのインスタンスです。
https://docs.oracle.com/javase/jp/6/api/java/lang/System.html#out

java.io.PrintStream#print(Object) は、その引数の String#valueOf(Object) の結果を返します。
https://docs.oracle.com/javase/jp/6/api/java/io/PrintStream.html#print(java.lang.Object)

java.lang.String#valueOf(Object) は、以下のような処理をします。
https://docs.oracle.com/javase/jp/6/api/java/lang/String.html#valueOf(java.lang.Object)

引数が null の場合は、"null" に等しい文字列。そうでない場合は、obj.toString() の値


toString() メソッドは、全てのクラスの基底クラスである Object クラスに実装があります。
自前で定義しない限り、以下のような値を返します。
https://docs.oracle.com/javase/jp/6/api/java/lang/Object.html#toString()

Object クラスの toString メソッドは、オブジェクトの派生元のクラス名、アットマーク (@)、およびオブジェクトのハッシュコードの符号なし 16 進表現から構成される文字列を返します。つまり、このメソッドは次の値と等しい文字列を返します。

  getClass().getName() + '@' + Integer.toHexString(hashCode())

id:moon-fondu

outって定数みたいなやつだったんですね。
変数はよく聞きますが、定数という概念がJavaに会ったのは知りませんでした。
予約語と同義のような気もしますが。

a-kuma3さんのコメントと、

標準入出力
http://wisdom.sakura.ne.jp/programming/java/java43.html

を読んで、大まかに理解できました。

valueOfはメソッドみたいすね、String型に変える。
toStringと似ていますね。

String.valueOf() と toString() の違い
http://write-remember.com/program/java/integertostring/

も、判りました。
ただ、私はvalueOfというコードは書いてないので、なぜvalueOfが出てくるのかが判らなくて…。
「@532760d8」「@57fa26b7」が出てきた理由はわかりました。
「toString ハッシュコード」で調べたら色々toStringメソッドについて知ることができました、ハッシュコードのヒント、ありがとうございます。

面白いことに、

-------------------
package testprogramme;

class Tsukareta {
public void naze() {
}
}
-------------------

と、return文で呼び出し元に返す文字列などを指定しないと、同じくハッシュコードが出てきました。

System.out.println("mag1:" + mag1.toString());
System.out.println("mag2:" + mag2.toString());

としても結果が同じである理由が、

[Java]toString()メソッドの有用な使い方 | KENスクールブログ
https://www.kenschool.jp/blog/?p=4020

で知ることが出来ました。

JavaのtoStringメソッドは常にオーバーライドする
http://4geek.net/tostring-method-always-overrides-on-java/

も読んでみましたが、オーバーライドの理解がまだ不十分なので、後回しにしたいと思います。
一旦、

「定義されていない変数(オブジェクト)であるmag1、mag2の内容をprintlnで出力しようとすると、Objectクラスから継承されているtoStringメソッドも実行され、オブジェクトのハッシュコードの符号なし16進表現から構成される文字列を返す」「toStringメソッドのブロック内で、return文で戻り値を指定すると、呼び出し元にその値を返す」

と理解しました。
認識違い等ありましたらご指摘いただけますと幸いです。
ありがとうございました<m(__)m>

2019/08/05 02:10:07
id:a-kuma3

その理解で良いと思います。

2019/08/05 08:29:09

その他の回答1件)

id:a-kuma3 No.1

回答回数4974ベストアンサー獲得回数2154ここでベストアンサー

ポイント600pt

System.out は、java.io.PrintStream というクラスのインスタンスです。
https://docs.oracle.com/javase/jp/6/api/java/lang/System.html#out

java.io.PrintStream#print(Object) は、その引数の String#valueOf(Object) の結果を返します。
https://docs.oracle.com/javase/jp/6/api/java/io/PrintStream.html#print(java.lang.Object)

java.lang.String#valueOf(Object) は、以下のような処理をします。
https://docs.oracle.com/javase/jp/6/api/java/lang/String.html#valueOf(java.lang.Object)

引数が null の場合は、"null" に等しい文字列。そうでない場合は、obj.toString() の値


toString() メソッドは、全てのクラスの基底クラスである Object クラスに実装があります。
自前で定義しない限り、以下のような値を返します。
https://docs.oracle.com/javase/jp/6/api/java/lang/Object.html#toString()

Object クラスの toString メソッドは、オブジェクトの派生元のクラス名、アットマーク (@)、およびオブジェクトのハッシュコードの符号なし 16 進表現から構成される文字列を返します。つまり、このメソッドは次の値と等しい文字列を返します。

  getClass().getName() + '@' + Integer.toHexString(hashCode())

id:moon-fondu

outって定数みたいなやつだったんですね。
変数はよく聞きますが、定数という概念がJavaに会ったのは知りませんでした。
予約語と同義のような気もしますが。

a-kuma3さんのコメントと、

標準入出力
http://wisdom.sakura.ne.jp/programming/java/java43.html

を読んで、大まかに理解できました。

valueOfはメソッドみたいすね、String型に変える。
toStringと似ていますね。

String.valueOf() と toString() の違い
http://write-remember.com/program/java/integertostring/

も、判りました。
ただ、私はvalueOfというコードは書いてないので、なぜvalueOfが出てくるのかが判らなくて…。
「@532760d8」「@57fa26b7」が出てきた理由はわかりました。
「toString ハッシュコード」で調べたら色々toStringメソッドについて知ることができました、ハッシュコードのヒント、ありがとうございます。

面白いことに、

-------------------
package testprogramme;

class Tsukareta {
public void naze() {
}
}
-------------------

と、return文で呼び出し元に返す文字列などを指定しないと、同じくハッシュコードが出てきました。

System.out.println("mag1:" + mag1.toString());
System.out.println("mag2:" + mag2.toString());

としても結果が同じである理由が、

[Java]toString()メソッドの有用な使い方 | KENスクールブログ
https://www.kenschool.jp/blog/?p=4020

で知ることが出来ました。

JavaのtoStringメソッドは常にオーバーライドする
http://4geek.net/tostring-method-always-overrides-on-java/

も読んでみましたが、オーバーライドの理解がまだ不十分なので、後回しにしたいと思います。
一旦、

「定義されていない変数(オブジェクト)であるmag1、mag2の内容をprintlnで出力しようとすると、Objectクラスから継承されているtoStringメソッドも実行され、オブジェクトのハッシュコードの符号なし16進表現から構成される文字列を返す」「toStringメソッドのブロック内で、return文で戻り値を指定すると、呼び出し元にその値を返す」

と理解しました。
認識違い等ありましたらご指摘いただけますと幸いです。
ありがとうございました<m(__)m>

2019/08/05 02:10:07
id:a-kuma3

その理解で良いと思います。

2019/08/05 08:29:09
id:kaoato No.2

回答回数236ベストアンサー獲得回数86

ポイント300pt
class Tsukareta {

は、

class Tsukareta extends  java.lang.Object {

と同じ意味

class Tsukareta extends  java.lang.Object {
 public String toString() {
  return "どうしてもこの文字が?";
 }
}

と書くと、親クラスの「toString()」をオーバーライト(上書き)することになる。

toString()自体がない場合は、親クラスのtoString()がそのまま呼ばれる。


System.out.println()
は、
java.lang.System.out.println()
と同じ。

https://docs.oracle.com/javase/jp/7/api/index.html?java/lang/System.html

>outって定数みたいなやつだったんですね

クラスの定義をみればわかると思う。

id:moon-fondu

そうだったんですね。
今まで、何気なくクラス宣言してましたが、Objectクラスが継承されていたのは知りませんでした!

----------------------
package testprogramm;

class Tsukareta extends java.lang.Object {
public String toString() {
return null;
}
}
----------------------

としてもコンパイルエラーは起きず、

――――――――
mag1:null
mag2:null
mag1 == mag2->false
mag1.equals(mag2)->false
――――――――

という結果が出てきました!
「class Equalityoperator」も、「class Equalityoperator extends java.lang.Object」にできまして、「System.out.println」も、「java.lang.System.out.println」としても問題なかったです。

ありがとうございました。

2019/08/06 20:50:36

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません