【Java】文字列に変換したい!toStringの使い方とvalueOfとの違いは?

【Java】文字列に変換したい!toStringの使い方とvalueOfとの違いは?

のかな

開発エンジニア/Java4年/ボールド歴4年

toStringメソッドは文字列に変換する際に使用するメソッドです。数値型やオブジェクトの中身を文字列として取得することができます。ただし自作クラスのオブジェクトの場合、中身を意図した文字列として取得するにはオーバーライドする必要があります。

そんなtoStringメソッドですが、実はJavaを学ぶ中で初期の段階から知らず知らずのうちにお世話になっているメソッドですべてのJavaエンジニアにとってなじみ深いメソッドなんです。

就活生向け特設ページ

1.toStringメソッドとは

1-1.lang.Objectクラスで定義されているメソッド

toStringメソッドはObjectクラスで定義されているメソッドです。APIには以下のように記載されています。

toStringメソッドとは

JavaではすべてのクラスがObjectクラスを継承していますので、どのクラスでもtoStringメソッドを使うことが可能です。

1-2.文字列に変換するためのメソッド

APIにも書かれている通り、toStringメソッドはオブジェクトをテキストで表すための文字列を返すメソッドです。

たとえばオブジェクトを引数にしたSystem.out.printメソッドでは内部でString.valueOfメソッドが呼び出されています。このvalueOfメソッドで引数の型に応じたtoStringメソッドが呼び出されることで文字列が出力される仕組みになっています。

冒頭で知らずのうちにお世話になっているなじみ深いメソッドといったのはまさにこの点で、toStringメソッドを使うことで様々な型のクラスを文字列として取得することができるのです。

1-3.int型をtoStringメソッドでString型に変換しよう

では、ここからは具体的にtoStringメソッドの使い方を見ていきましょう。まずはプリミティブ型の中でも数値型の代表としてint型を例にします。(他のプリミティブ型も基本的な使い方は共通です)

int num1 = 123;
int num2 = 456;
System.out.println(num1 + num2);

String strNum1 = Integer.toString(num1);
String strNum2 = Integer.toString(num2);
System.out.println(strNum1 + strNum2);

上記のコードの結果は、

---
579
123456
---

となります。

num1とnum2int型の変数なのでprintlnメソッドの引数で+演算子を使用した場合は値同士の足し算が行われます。対してstrNum1strNum2の中身はIntegerクラスのtoStringメソッドでint型のnum1num2String型に変換したものです。この場合printlnメソッドでは引数がString型同士のため文字列連結されます。

ここでのポイントはint型はプリミティブ型のためそのままではメソッドを使うことができません。toStringメソッドでString型に変換するにはラッパークラスであるIntegerクラスからメソッドを呼び出す必要があります。

以上がtoStringメソッドを使ったint型のString型への変換方法です。

System.out.printメソッドでプリミティブ型を引数にした場合もラッパークラスのtoStringメソッドを経て出力されています。(+演算子による評価はメソッド実行前のため、先にint型として足し算されます)ラッパークラスはプリミティブ型を参照型として扱うためのクラスです。他のプリミティブ型にもそれぞれラッパークラスが用意されているので、気になる方は調べてみてください。


2.自作クラスのtoStringメソッドはオーバーライドしよう

次に、自作クラスでtoStringメソッドを意図して使うにはオーバーライドをする必要がある、ということを見ていきましょう。

package example;

public class Dog {
	String name;
	int age;
	String kind;

	public Dog() {
		this.name = "ポチ";
		this.age = 3;
		this.kind = "チワワ";
	}
}

上記のような自作クラスを用意して、mainメソッドで以下を実行します。

Dog dog = new Dog();
System.out.println(dog);

結果は以下です。

---
example.Dog@48140564
---

Dogクラスを文字列で出力したいのに、一見して意味のわからない結果が出力されました。ここで、1-1で紹介したObjectクラスのAPIで定義されているtoStringメソッドの内容を思い出してください。注目するのは以下の部分です。

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

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

つまり自作クラスでtoStringメソッドが呼び出されるときにオーバーライドしていない場合は継承元であるObjectクラスのtoStringメソッドが呼び出されるため、意図しない文字列が出力されてしまうのです。APIに「このメソッドをオーバーライドすることをお勧めします。」と書かれているのはこのためです。

自作クラスでtoStringメソッドを使用して意図した文字列を出力したいのなら、きちんとオーバーライドして出力したい内容を実装する必要があるよ、そうでなきゃとりあえずObjectクラスで定義している内容で出力しとくね、ということです。

それでは、先ほどのDogクラスでtoStringクラスをオーバーライドしてみましょう。Dogクラスに以下のコードを追加します。

@Override
public String toString() {
	return "Dog [name=" + name + ", age=" + age + ", kind=" + kind + "]";
}

そして、再びmainメソッドで以下を実行します。

Dog dog = new Dog();
System.out.println(dog);

すると結果は以下となります。

---
Dog [name=ポチ, age=3, kind=チワワ]
---

Dogクラスで定義したtoStringメソッドの内容が出力されました。このように自作クラスではtoStringメソッドをオーバーライドすることで意図した文字列を出力できることがおわかりいただけたかと思います。オーバーライドについて詳しく知りたい方は以下の記事を参考にしてみてください。

関連記事

3.toStringメソッドの注意点、valueOfメソッドとの違い

toStringを使用する上での注意点としては、nullのオブジェクトを変換しようとするとNullPointerExceptionが発生してしまうことが挙げられます。nullチェックを行うかnullでないことが保証できる状態から呼び出すようにしましょう。

具体的に見てみましょう。

Dog dog = null;
System.out.println(dog);
String strDog = dog.toString();
System.out.println(strDog);

結果は以下です。

---
null
Exception in thread “main” java.lang.NullPointerException
    at sample/example.Main.main(Main.java:9)
---

行数がないのでわかりにくいですが、最初のprintlnメソッドではnullが出力され次の行のtoStringメソッドの呼び出しでNullPointerExceptionが発生しています。(2回目のprintlnメソッドは実行されない)

ここで注目したいのは、NullPointerExceptionが発生するのは、
System.out.println(dog);
ではなく、
String strDog = dog.toString();
であるという点です。

ここで「printlnメソッドは内部でtoStringメソッドが呼び出されているはずでは?」と思った方は鋭いです!

1-2でprintメソッドやprintlnメソッドでは内部でString.valueOfメソッドが呼び出され、valueOfメソッドからtoStringメソッドを呼び出すといいました。実はString.valueOfメソッドではオブジェクトがnullかどうかを判定し、nullの場合は文字列の”null”、そうでない場合はtoStringメソッドを呼び出すようになっています。そのためSystem.out.println(dog);の行ではそもそもtoStringメソッドは呼び出されていないのです。

String.valueOfメソッドも様々な型をString型に変換することができます。toStringメソッドと用途は似ていますが両者ではnullに対する動作の違いがあることを覚えておいてください。

4.まとめ

toStringメソッドの使い方がわかれば自作クラスのオブジェクトの中身を確認することも自在にできるようになります。

仕組みさえ理解してしまえばさほど難しくないのでぜひこの機会に自分のものにしてください。

私たちは、全てのエンジニアに市場価値を高め自身の望む理想のキャリアを歩んでいただきたいと考えています。もし、今あなたが転職を検討しているのであればこちらの記事をご一読ください。理想のキャリアを実現するためのヒントが見つかるはずです。

『技術力』と『人間力』を高め市場価値の高いエンジニアを目指しませんか?

私たちは「技術力」だけでなく「人間力」の向上をもって遙かに高い水準の成果を出し、関わる全ての人々に感動を与え続ける集団でありたいと考えています。

高い水準で仕事を進めていただくためにも、弊社では次のような環境を用意しています。

  • 定年までIT業界で働くためのスキル(技術力、人間力)が身につく支援
  • 「給与が上がらない」を解消する6ヶ月に1度の明確な人事評価制度
  • 平均残業時間17時間!毎週の稼動確認を徹底しているから実現できる働きやすい環境

現在、株式会社ボールドでは「キャリア採用」のエントリーを受付中です。

まずは以下のボタンより弊社の紹介をご覧いただき、あなたの望むキャリアビジョンをエントリーフォームより詳しくお聞かせください。

コメント

文系IT未経験歓迎!株式会社ボールドの 採用エントリー を受付中!
文系IT未経験歓迎!
株式会社ボールドの 採用エントリー を受付中!