今、このようなコードがあります。
-------------------------
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
-----------------------
という結果が出力されます。
ここで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桁の文字列が出てきたのか、その理由が知りたいです。
調べても考えてもわからず疲れ果ててしまいまして…お力添えをいただけますと幸いです。
よろしくお願い致します。
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())
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())
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>
その理解で良いと思います。
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って定数みたいなやつだったんですね
クラスの定義をみればわかると思う。
そうだったんですね。
今まで、何気なくクラス宣言してましたが、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」としても問題なかったです。
ありがとうございました。
outって定数みたいなやつだったんですね。
2019/08/05 02:10:07変数はよく聞きますが、定数という概念が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 08:29:09