Javaでは、との間に違いはString.valueOf(Object)
ありObject.toString()
ますか?これらのための特定のコード規約はありますか?
null
最初にチェックすることを除いて、それを正確に行います。
Javaでは、との間に違いはString.valueOf(Object)
ありObject.toString()
ますか?これらのための特定のコード規約はありますか?
null
最初にチェックすることを除いて、それを正確に行います。
回答:
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
}
String.valueOf(null)
、実際にを呼び出すことはできません。これはNPEです。nullのオブジェクトに対してのみ機能します。
String.valueOf(null)
実際にはvalueOf(char[])
過負荷に解決されます。これはchar[]
がより具体的なタイプであるためObject
です。
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()
Javaでは、String.valueOf(Object)とObject.toString()の間に違いはありますか?
はい。(さらに、オーバーロードを検討する場合はさらに!)
Javadocは、説明、String.valueOf((Object) null)
によって特殊なケースとして扱われるvalueOf
方法と値が"null"
返されます。対照的に、null.toString()
NPEを提供します。
javadocにもかかわらず、String.valueOf(null)
(違いに注意してください!)NPE が得られることがわかります。説明はあいまいです:
には多数のオーバーロードがありますが、String.valueOf
ここで関連するものは2つString.valueOf(Object)
ありString.valueOf(char[])
ます。
式String.valueOf(null)
では、割り当てはすべての参照型と互換性があるため、これらのオーバーロードの両方が適用されnull
ます。
該当するオーバーロードが2つ以上ある場合、JLSは、最も具体的な引数タイプのオーバーロードが選択されると言います。
char[]
はのサブタイプなのでObject
、より具体的です。
したがって、String.valueOf(char[])
オーバーロードが呼び出されます。
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()
。
ほとんどはすでに他の回答で言及されていますが、完全を期すために追加します。
.toString()
にはObject
-classの実装ではないため、プリミティブはありません。String.valueOf
。使用できるのです。String.valueOf
指定されたオブジェクトをnull
String "null"
に変換しますが.toString()
、NullPointerException
ます。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);
これはtest
STDOUTに出力されます。
と.toString()
しかし、それは動作しません。
String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);
これにより、次のエラーが発生します。
java.lang.ClassCastException
:クラスjava.lang.String
をクラスにキャストできませんjava.lang.Integer
理由については、この分離された質問とその回答を参照できます。要するに:
.toString()
、それは最初にコンパイルし、オブジェクトを評価し、ここへのキャストT
(あるString
とInteger
ここではキャストが)をもたらすであろうClassCastException
。String.valueOf
すると、コンパイル中のT
ようObject
にジェネリックが表示され、それがであることについてさえ気になりませんInteger
。そのため、(コンパイラが無視する)Object
to をキャストObject
します。次に、を使用しString.valueOf(Object)
、String
期待どおりの結果になります。したがって、内部でパラメータString.valueOf(Object)
に対してaを実行する場合でも.toString()
、キャストはスキップされ、そのように扱われるObject
ためClassCastException
、の使用で発生するを回避しました.toString()
。ただ、それは間のこの追加の違いを言及する価値だと思ったString.valueOf
し、.toString()
ここにも。
("" + x)
コンパイルされましたがString.valueOf(x)
、もっと複雑なものはすべて使用していましたStringBuffer
(StringBuilder
当時はありませんでした)。
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();
}
2つの方法のもう1つの大きな違いは、変換するオブジェクトが配列である場合です。
Object.toString()を使用して配列を変換すると、何らかのガベージ値(@の後に配列のハッシュコードが続く)が返されます。
人間が読めるtoString()を取得するには、String.valueOf(char []);を使用する必要があります。plzは、このメソッドがchar型の配列に対してのみ機能することに注意してください。配列を文字列に変換するには、Arrays.toString(Object [])を使用することをお勧めします。
2つ目の違いは、オブジェクトがnullの場合、ValueOf()は文字列「null」を返しますが、toString()はnullポインタ例外を返します。
違いは正確には言えませんが、バイトレベルで操作すると違いがあるようです。次の暗号化シナリオでは、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()
valueOf(char[])
なく、実際に呼び出しているということですvalueOf(Object)
。の動作はvalueOf(char[])
とは大きく異なりchar[].toString()
ます。しかし、どちらにしても、質問が尋ねたものとは異なるオーバーロードを呼び出しているため、この回答は適切ではありません。
以下は、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);
}
String.valueOf
、使用されます。toStringをオーバーライドするオブジェクトの場合、String.valueOfが代わりにそれを呼び出す可能性があると思います。しかし、その部分についてはわかりません。