String.valueOf()とObject.toString()


132

Javaでは、との間に違いはString.valueOf(Object)ありObject.toString()ますか?これらのための特定のコード規約はありますか?


10
プリミティブ型には「toString」がないためString.valueOf、使用されます。toStringをオーバーライドするオブジェクトの場合、String.valueOfが代わりにそれを呼び出す可能性があると思います。しかし、その部分についてはわかりません。
ブランドン、

@ブランドンあなたは正しいです、それはnull最初にチェックすることを除いて、それを正確に行います。
azurefrog 2014

ここの最初のコメントは、それが正しければ最も理にかなっていると思います。ターゲットがプリミティブ型である特定の状況では、String.valueOfを使用する必要があります。
Donato 2017

回答:


177

Javaのドキュメントによれば、次をString.valueOf()返します:

引数がの場合null、次に等しい文字列"null"。それ以外の場合は、の値obj.toString()が返されます。

そのため、追加のメソッド呼び出しを除いて、実際に違いはありません。

また、のObject#toString場合、インスタンスがの場合null、a NullPointerExceptionがスローされるので、おそらく安全ではありません。

public static void main(String args[]) {  
    String str = null;
    System.out.println(String.valueOf(str));  // This will print a String equal to "null"        
    System.out.println(str.toString()); // This will throw a NullPointerException
} 

6
これが最良の答えです。コードではなく、javadocsを読んで信頼してください。(コードは基本的に、Javaのバージョンやリリースによって異なる可能性があります。)
Stephen C

7
@ブランドン-不正解。javadocを無効にするように動作が変更された場合にのみ変更する必要があります。1)この方法で発生する可能性はゼロです。彼らは仕様の変更を正当化するような変更を行うことはありません。もしそうなら、彼らは仕様変更するでしょう。2)それは私のアドバイスを無効にしません。javadocを読むと、文書化された動作が変更されていることがわかります。
スティーブンC

2
例外をスローするメソッドはより安全ではないでしょうか?通常、コードがNullPointerExceptionをスローする場合、それは一種の良いことです。今のところ、開発者にとっては気分が悪いかもしれませんが(「いや、いや、今は戻ってコードを修正する必要があります」)、エラーがスローされたため、何かを修正する必要があることがわかりました。逆に言えば、「null」をユーザーに直接公開しているので、明示的にチェックしない限りエラーは報告されません。
Tim M.

1
明確にするためにString.valueOf(null)、実際にを呼び出すことはできません。これはNPEです。nullのオブジェクトに対してのみ機能します。
Noumenon

1
それは説明ではありません。はString.valueOf(null)実際にはvalueOf(char[])過負荷に解決されます。これはchar[]がより具体的なタイプであるためObjectです。
スティーブンC

17

String.valueOf(Object)とObject.toString()の違いは次のとおりです。

1) 文字列がnullの場合、

String.valueOf(Object)はを返しnullますObject::toString()が、nullポインタ例外をスローします。

public static void main(String args[]){  
    String str = null;

    System.out.println(String.valueOf(str));  // it will print null        
    System.out.println(str.toString()); // it will throw NullPointerException        
}  

2)署名:

StringクラスのvalueOf()メソッドは静的です。一方、StringクラスのtoString()メソッドは静的ではありません。

文字列のvalueOf()メソッドのシグネチャまたは構文を以下に示します。

public static String valueOf(boolean b)  
public static String valueOf(char c)  
public static String valueOf(char[] c)  
public static String valueOf(int i)  
public static String valueOf(long l)  
public static String valueOf(float f)  
public static String valueOf(double d)  
public static String valueOf(Object o)

文字列のtoString()メソッドの署名または構文を以下に示します。

public String toString()

13

Javaでは、String.valueOf(Object)とObject.toString()の間に違いはありますか?

はい。(さらに、オーバーロードを検討する場合はさらに!)

Javadocは、説明、String.valueOf((Object) null)によって特殊なケースとして扱われるvalueOf方法と値が"null"返されます。対照的に、null.toString() NPEを提供します。

過負荷

javadocにもかかわらず、String.valueOf(null)(違いに注意してください!)NPE 得られることがわかります。説明はあいまいです:

  1. には多数のオーバーロードがありますが、String.valueOfここで関連するものは2つString.valueOf(Object)ありString.valueOf(char[])ます。

  2. String.valueOf(null)では、割り当てはすべての参照型と互換性があるため、これらのオーバーロードの両方が適用されnullます。

  3. 該当するオーバーロードが2つ以上ある場合、JLSは、最も具体的な引数タイプのオーバーロードが選択されると言います。

  4. char[]はのサブタイプなのでObjectより具体的です。

  5. したがって、String.valueOf(char[])オーバーロードが呼び出されます。

  6. String.valueOf(char[])引数がnull配列の場合、NPEをスローします。とは異なりString.valueOf(Object)null特別なケースとして扱われません。

(これを使用javap -cして、String.valueOf(null)呼び出しを持つメソッドのコードを調べることで確認できます。呼び出しに使用されるオーバーロードを確認してください。)

別の例は、valueOf(char[])過負荷の違いをさらに明確に示しています。

char[] abc = new char[]('a', 'b', 'c');
System.out.println(String.valueOf(abc));  // prints "abc"
System.out.println(abc.toString());       // prints "[C@...."

これらのための特定のコード規約はありますか?

番号。

使用するコンテキストの要件に最も適したものを使用してください。(動作するフォーマットが必要ですか?nullですか?)

注:これはコード規約ではありません。それは単なる常識プログラミングです。文体的な慣習や「ベストプラクティス」の定説に従うよりも、コードが正しいことが重要です。


個人的な意見:

一部の開発者は、ヌルに対して「防御」する(IMO)悪い習慣を身につけています。したがって、nullのテストがたくさんあり、nullを特殊なケースとして扱うことがわかります。このアイデアは、NPEの発生を妨げているようです。

これは悪い考えだと思います。特に、見つけたときに何をするのnullが「良くなる」ことをしようとするのは悪い考えだと思います。null

一般に、アプリケーションやAPI設計でが非常に具体的な意味を持たnullない限り、最初から存在しないようにすることnullをお勧めします。そのため、多くの防御的コーディングでNPEを回避するのではなく、NPEを発生させ、NPE nullをトリガーした予期しないソースを追跡して修正することをお勧めします。

これはどのようにここに当てはまりますか?

よく考えてみれば、使用は「良いことをする」ための方法String.valueOf(obj) かもしれません。それは避けられるべきです。以下のために、それは予想外である場合objであることをnull文脈では、それが使用することをお勧めしますobj.toString()


5

ほとんどはすでに他の回答で言及されていますが、完全を期すために追加します。

  1. プリミティブ.toString()にはObject-classの実装ではないため、プリミティブはありません。String.valueOf。使用できるのです。
  2. String.valueOf指定されたオブジェクトをnullString "null"に変換しますが.toString()NullPointerExceptionます。
  3. String.valueOfようなものが使用される場合、コンパイラはデフォルトで使用しますString s = "" + (...);。これがNPEではなくObject t = null; String s = "" + t;Stringになる理由"null"です。編集:実は、それが使用されますStringBuilder.append、ではありませんString.valueOf。ここで私が言ったことは無視してください。

これらに加えて、実際にはさまざまな結果String.valueOf.toString()持つユースケースを次に示します。

次のようなジェネリックメソッドがあるとします。

public static <T> T test(){
  String str = "test";
  return (T) str;
}

そして、次のIntegerようなタイプで呼び出しますMain.<Integer>test()

それを使って文字列を作成するとString.valueOfうまくいきます:

String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);

これはtestSTDOUTに出力されます。

.toString()しかし、それは動作しません。

String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);

これにより、次のエラーが発生します。

java.lang.ClassCastException:クラスjava.lang.Stringをクラスにキャストできませんjava.lang.Integer

オンラインでお試しください。

理由については、この分離された質問とその回答を参照できます。要するに:

  • 使用する場合.toString()、それは最初にコンパイルし、オブジェクトを評価し、ここへのキャストT(あるStringIntegerここではキャストが)をもたらすであろうClassCastException
  • これを使用String.valueOfすると、コンパイル中のTようObjectにジェネリックが表示され、それがであることについてさえ気になりませんInteger。そのため、(コンパイラが無視する)Objectto をキャストObjectします。次に、を使用しString.valueOf(Object)String期待どおりの結果になります。したがって、内部でパラメータString.valueOf(Object)に対してaを実行する場合でも.toString()、キャストはスキップされ、そのように扱われるObjectためClassCastException、の使用で発生するを回避しました.toString()

ただ、それは間のこの追加の違いを言及する価値だと思ったString.valueOfし、.toString()ここにも。


前回私がこれに注意を払ったとき、これはJDK 1.2の周りにあり、に("" + x)コンパイルされましたがString.valueOf(x)、もっと複雑なものはすべて使用していましたStringBufferStringBuilder当時はありませんでした)。
Neil

4

String.valueOf(Object)そしてObject.toString()文字通り同じものです。

String.valueOf(Object)の実装を見ると、String.valueOf(Object)基本的toString()には適切なオブジェクトのnullセーフな呼び出しであることがわかります。

Returns the string representation of the Object argument.

Parameters:
    obj an Object.
Returns:
    if the argument is null, then a string equal to "null"; 
    otherwise, the value of obj.toString() is returned.
See also:
    Object.toString()

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

trueではありません。char配列でvalueOfとtoStringの両方を使用して、目を楽しませてください。
Artanis

3

最も重要な違いは、null文字列参照の処理方法です。

String str = null;
System.out.println("String.valueOf gives : " + String.valueOf(str));//Prints null
System.out.println("String.toString gives : " + str.toString());//This would throw a NullPointerExeption

1

引数がのnull場合、String.valueOf戻り値"null"はですが、をObject.toStringスローしますが、それNullPointerExceptionだけが異なります。


0

2つの方法のもう1つの大きな違いは、変換するオブジェクトが配列である場合です。

Object.toString()を使用して配列を変換すると、何らかのガベージ値(@の後に配列のハッシュコードが続く)が返されます。

人間が読めるtoString()を取得するには、String.valueOf(char []);を使用する必要があります。plzは、このメソッドがchar型の配列に対してのみ機能することに注意してください。配列を文字列に変換するには、Arrays.toString(Object [])を使用することをお勧めします。

2つ目の違いは、オブジェクトがnullの場合、ValueOf()は文字列「null」を返しますが、toString()はnullポインタ例外を返します。


こんにちは@Tomこれは任意の型の配列に当てはまりますが、Arrays.toString(Object [])を使用している場合は、任意の型の配列を文字列に変換できます。
チンタンサッカー2017年

こんにちは@Tom Object.toString()がガベージ値を返すのは、どのタイプの配列でもtrueです。String.valueOf(Array)がcharタイプの配列に対してのみ正しい文字列を提供するのは正しいことです。私はそれを述べるべきでした、ありがとう、私はそれを編集します。
チンタンサッカー2017年

1
これはガベージ値ではなく、クラス名とハッシュコード(JavaDoc)です。
Tom

-1

違いは正確には言えませんが、バイトレベルで操作すると違いがあるようです。次の暗号化シナリオでは、Object.toString()は復号化できない値を生成しましたが、String.valueOf()は意図したとおりに機能しました...

private static char[] base64Encode(byte[] bytes) 
{   
    return Base64.encode(bytes);
}

private static String encrypt(String encrypt_this) throws GeneralSecurityException, UnsupportedEncodingException 
{
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
    pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));

     //THIS FAILED when attempting to decrypt the password
    //return base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))).toString(); 

    //THIS WORKED
    return String.valueOf(base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))));
}//end of encrypt()

なぜ失敗したのですか?どうしたの?
Yousha Aleayoub 2016

説明ではvalueOf(char[])なく、実際に呼び出しているということですvalueOf(Object)。の動作はvalueOf(char[])とは大きく異なりchar[].toString()ます。しかし、どちらにしても、質問が尋ねたものとは異なるオーバーロードを呼び出しているため、この回答は適切ではありません。
スティーブンC

-2

以下は、jdk8u25のソースで説明されているjava.lang.String.valueOfの実装を示しています。だから私のコメントによると、違いはありません。「Object.toString」を呼び出します。プリミティブ型の場合は、それをそのオブジェクト形式でラップし、「toString」を呼び出します。

下記参照:

/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */


    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

    public static String valueOf(char data[]) {
        return new String(data);
    }

    public static String valueOf(char data[], int offset, int count) {
        return new String(data, offset, count);
    }

    public static String copyValueOf(char data[], int offset, int count) {
        return new String(data, offset, count);
    }

    public static String copyValueOf(char data[]) {
        return new String(data);
    }

    public static String valueOf(boolean b) {
        return b ? "true" : "false";
    }

    public static String valueOf(char c) {
        char data[] = {c};
        return new String(data, true);
    }

    public static String valueOf(int i) {
        return Integer.toString(i);
    }

    public static String valueOf(long l) {
        return Long.toString(l);
    }

    public static String valueOf(float f) {
        return Float.toString(f);
    }

    public static String valueOf(double d) {
        return Double.toString(d);
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.