たなかのJava日記

どんなことをやったか(学んだか)、どこで詰まったか(わからなかったか)、どこで工夫したかの記録です。

【Java】インスタンスの文字列表現について

https://mtanaka.hatenablog.com/entry/2022/05/25/233000

前回インスタンスの5大操作の前提知識を学びました。
本日はそのうちの一つ、インスタンスの文字列表現についてについてです。


【これから学ぶこと】
toString()を使用し、インスタンスの内容を適切かつ期待する文字列表現で行うこと


【toString()とは】
インスタンスの内容を、人が読んで理解できる文字列で表現したものとして返すメソッド

全てのインスタンスがtoString()を持つことが保証されているからこそ、
インスタンスの中身の情報を知りたいなら、とにかくtoString()を呼び出せばよいと考えることができます。


【活躍する場所・どんな時に使われることが多いか】
デバッグやログ出力など


【toString()が使用されている例】
System.out.println()

良く利用されるSystem.out.println()は、
引数にインスタンスを渡すとそのtoString()を呼び出して文字列表現を取り出し、画面に表示します。
例えば、Parson型の変数aに入っているインスタンスの中身について知りたい場合は、以下のように書きます。


package jp.co.mtanaka

public class Sample1 {
    public static void main(String[] args) {
        Parson a = new Parson("ノブ", 42);
        System.out.println(a);
    }
}
package jp.co.mtanaka

public class Parson {
    private String name;
    private int age, mp;

    public Parson(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

【toString()が使用した際の問題点】
One.Parson@776ec8df
上記は先程の実行結果になりますが、わかりやすいような出力ではありません。

希望している実行結果は、
人(名前=ノブ/年齢=42)
のようなわかりやすい出力です。


【toString()のは何をしているのか】
先程のコードで動作しているのは、暗黙の親クラスであるObjectのtoString()です。

そのObjectクラスのtoStringメソッドは、
オブジェクトがインスタンスになっている元のクラスの名前、アットマーク文字「@」、
およびオブジェクトのハッシュ・コードの符号なし16進数表現から構成される文字列を返します。
つまり、このメソッドは次の値と等しい文字列を返します。

getClass().getName() + ‘@’ + Integer.toHexString(hashCode())



【toString()を使用し、インスタンスの内容を適切かつ期待する文字列表現で行うためには?】
Java言語の開発者は「すべてのクラスが持っておくべき機能」いわば、
最低限備えて置いてほしいというをメソッドにしてObjectクラスに備えるようにしています。

これは、インスタンス同士の内容が同じかチェックしたり、
インスタンスの内容がどのようなものかを文字情報として表示したりしたいことが頻繁にあるためです。

しかし、あるクラスがどのような文字列表現を返すべきは、結局はそのクラスを作った人にしかわかりません。
今回作成したクラスで、人(名前=ノブ/年齢=42)などと好みの出力結果が得られないのは当然です。
なので、期待する文字列表現は私たち自身が親クラス(Objectクラス)の不適切なtoString()を
オーバーライドして、適切な文字列表現を返すように動作を上書きすればよいのです。

package jp.co.mtanaka;

public class Parson {
    private String name;
    private int age, mp;

    public Parson(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // toString()オーバーライドして、適切な文字列表現を返すように上書き
    @Override
    public String toString() {
        return "人(名前=" + this.name + "/年齢=" + this.age + "歳)";
    }
}

実行結果
人(名前=ノブ/年齢=42歳)


【まとめ】
toString()を使用し、インスタンスの内容を適切かつ期待する文字列表現で行うためには、
toString()をオーバーライドする。

新たなクラスを開発したら、toString()をオーバーライドしておくことで、開発者が意図した文字列表現を渡すことができる。

※Parsonとなっていますが、正しくはPersonでした。