Di Jawa, apakah ada perbedaan antara String.valueOf(Object)
dan Object.toString()
? Apakah ada konvensi kode khusus untuk ini?
null
terlebih dahulu.
Di Jawa, apakah ada perbedaan antara String.valueOf(Object)
dan Object.toString()
? Apakah ada konvensi kode khusus untuk ini?
null
terlebih dahulu.
Jawaban:
Menurut dokumentasi Java , String.valueOf()
pengembalian:
jika argumennya adalah
null
, maka string sama dengan"null"
; jika tidak, nilaiobj.toString()
dikembalikan.
Jadi seharusnya tidak ada perbedaan kecuali untuk permohonan metode tambahan.
Juga, dalam kasus Object#toString
, jika instansinya adalah null
, NullPointerException
akan dilempar, jadi bisa dibilang, itu kurang aman .
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)
, itu adalah NPE. Ini hanya berfungsi untuk objek yang null.
String.valueOf(null)
sebenarnya resolve ke valueOf(char[])
overload. Ini karena char[]
jenis yang lebih spesifik daripada Object
.
Perbedaan antara String.valueOf (Object) dan Object.toString () adalah:
1) Jika string adalah nol,
String.valueOf(Object)
akan kembali null
, sedangkan Object::toString()
akan membuang pengecualian pointer nol.
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) Tanda tangan:
metode valueOf () dari kelas String bersifat statis. sedangkan metode toString () dari kelas String tidak statis.
Tanda tangan atau sintaks dari metode valueOf () string diberikan di bawah ini:
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)
Tanda tangan atau sintaksis toString()
metode string diberikan di bawah ini:
public String toString()
Di Jawa, apakah ada perbedaan antara String.valueOf (Object) dan Object.toString ()?
Iya. (Dan lebih dari itu jika Anda mempertimbangkan kelebihan!)
Seperti yang dijelaskan javadoc , String.valueOf((Object) null)
akan diperlakukan sebagai kasus khusus oleh valueOf
metode dan nilai "null"
dikembalikan. Sebaliknya, null.toString()
hanya akan memberi Anda NPE.
Ternyata String.valueOf(null)
(perhatikan perbedaannya!) Memang memberikan NPE ... terlepas dari javadoc. Penjelasannya tidak jelas:
Ada sejumlah kelebihan String.valueOf
, tetapi ada dua yang relevan di sini: String.valueOf(Object)
dan String.valueOf(char[])
.
Dalam ekspresi String.valueOf(null)
, kedua kelebihan tersebut berlaku , karena null
penugasan tersebut kompatibel dengan jenis referensi apa pun.
Ketika ada dua atau lebih kelebihan yang berlaku , JLS mengatakan bahwa kelebihan untuk jenis argumen paling spesifik dipilih.
Karena char[]
ini adalah subtipe dari Object
, itu lebih spesifik .
Oleh karena itu String.valueOf(char[])
kelebihan disebut.
String.valueOf(char[])
melempar NPE jika argumennya adalah array nol. Tidak seperti String.valueOf(Object)
itu, itu tidak diperlakukan null
sebagai kasus khusus.
(Anda dapat mengonfirmasi ini dengan menggunakan javap -c
untuk memeriksa kode metode yang memiliki String.valueOf(null)
panggilan. Amati kelebihan beban yang digunakan untuk panggilan tersebut.)
Contoh lain menggambarkan perbedaan dalam valueOf(char[])
kelebihan beban bahkan lebih jelas:
char[] abc = new char[]('a', 'b', 'c');
System.out.println(String.valueOf(abc)); // prints "abc"
System.out.println(abc.toString()); // prints "[C@...."
Apakah ada konvensi kode khusus untuk ini?
Tidak.
Gunakan mana yang paling sesuai dengan persyaratan konteks di mana Anda menggunakannya. (Apakah Anda membutuhkan pemformatan untuk bekerja null
?)
Catatan: itu bukan konvensi kode. Itu hanya pemrograman akal sehat. Lebih penting bahwa kode Anda benar daripada mengikuti beberapa konvensi gaya atau dogma "praktik terbaik".
Opini pribadi:
Beberapa pengembang memperoleh (IMO) kebiasaan buruk "membela" terhadap nol. Jadi Anda melihat banyak tes untuk nulls, dan memperlakukan nulls sebagai kasus khusus. Idenya tampaknya mencegah NPE terjadi.
Saya pikir ini ide yang buruk. Secara khusus, saya pikir itu adalah ide yang buruk jika apa yang Anda lakukan ketika Anda menemukan null
adalah mencoba untuk "membuat yang baik" ... tanpa pertimbangan mengapa ada di null
sana.
Secara umum, lebih baik untuk menghindari null
keberadaan di tempat pertama ... kecuali jika null
memiliki arti yang sangat spesifik dalam aplikasi atau desain API Anda. Jadi, daripada menghindari NPE dengan banyak pengkodean defensif, lebih baik membiarkan NPE terjadi, dan kemudian melacak dan memperbaiki sumber yang tidak terduga null
yang memicu NPE.
Jadi bagaimana ini berlaku di sini?
Nah, jika Anda memikirkannya, menggunakan String.valueOf(obj)
bisa menjadi cara "membuat yang baik". Itu harus dihindari. Jika tidak terduga obj
berada null
dalam konteks, lebih baik digunakan obj.toString()
.
Sebagian besar telah disebutkan oleh jawaban lain, tetapi saya hanya menambahkannya untuk kelengkapan:
.toString()
karena mereka bukan implementasi dari Object
-class, jadi hanya String.valueOf
dapat digunakan.String.valueOf
akan mengubah objek yang diberikan null
ke String "null"
, sedangkan .toString()
akan melempar a NullPointerException
.String.valueOf
secara default ketika sesuatu seperti String s = "" + (...);
digunakan. Itulah sebabnya Object t = null; String s = "" + t;
akan menghasilkan String "null"
, dan bukan NPE. StringBuilder.append
, bukan String.valueOf
. Jadi abaikan apa yang saya katakan di sini.Selain itu, di sini sebenarnya kasus penggunaan di mana String.valueOf
dan .toString()
memiliki hasil yang berbeda:
Katakanlah kita memiliki metode generik seperti ini:
public static <T> T test(){
String str = "test";
return (T) str;
}
Dan kita akan menyebutnya dengan Integer
tipe seperti ini: Main.<Integer>test()
.
Ketika kami membuat sebuah String dengan String.valueOf
itu berfungsi dengan baik:
String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);
Ini akan menghasilkan test
STDOUT.
Dengan .toString()
Namun, itu tidak akan berhasil:
String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);
Ini akan menghasilkan kesalahan berikut:
java.lang.ClassCastException
: kelasjava.lang.String
tidak dapat dilemparkan ke kelasjava.lang.Integer
Mengenai alasannya, saya dapat merujuk pada pertanyaan yang terpisah ini dan jawabannya . Singkatnya:
.toString()
, pertama-tama akan mengkompilasi dan mengevaluasi objek, di mana pemain yang akan T
(yang merupakan pemain String
untuk Integer
kasus ini) akan menghasilkan ClassCastException
.String.valueOf
akan melihat generik T
sebagai Object
selama kompilasi dan bahkan tidak peduli itu menjadi Integer
. Jadi itu akan melemparkan Object
ke Object
(yang mengabaikan kompiler). Kemudian akan digunakan String.valueOf(Object)
, menghasilkan String
seperti yang diharapkan. Jadi meskipun String.valueOf(Object)
akan melakukan .toString()
pada parameter secara internal, kami sudah melewatkan para pemain dan diperlakukan seperti Object
, jadi kami telah menghindari ClassCastException
yang terjadi dengan penggunaan .toString()
.Hanya berpikir itu layak menyebutkan perbedaan tambahan antara String.valueOf
dan di .toString()
sini juga.
("" + x)
dikompilasi String.valueOf(x)
, tetapi sesuatu yang lebih rumit menggunakan StringBuffer
(kami tidak memiliki StringBuilder
itu).
String.valueOf(Object)
dan Object.toString()
secara harfiah adalah hal yang sama.
Jika Anda melihat implementasi String.valueOf (Object) , Anda akan melihat bahwa String.valueOf(Object)
pada dasarnya hanya permohonan null-safe dari toString()
objek yang sesuai:
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();
}
Perbedaan paling penting adalah cara mereka menangani referensi String nol.
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
Ada satu lagi perbedaan utama antara kedua metode ini ketika objek yang kita konversi adalah array.
Ketika Anda mengubah array menggunakan Object.toString () Anda akan mendapatkan beberapa jenis nilai sampah (@ diikuti oleh kode hash array).
Untuk mendapatkan toString () yang dapat dibaca manusia, Anda harus menggunakan String.valueOf (char []); harap dicatat bahwa metode ini hanya berfungsi untuk array tipe char. Saya akan merekomendasikan menggunakan Arrays.toString (Object []) untuk mengubah array ke String.
Perbedaan kedua adalah ketika objeknya nol, ValueOf () mengembalikan sebuah String "null", sedangkan toString () akan mengembalikan pengecualian pointer nol.
Saya tidak bisa mengatakan dengan tepat apa perbedaannya tetapi tampaknya ada perbedaan ketika beroperasi pada level byte. Dalam skenario enkripsi berikut, Object.toString () menghasilkan nilai yang tidak dapat didekripsi sedangkan String.valueOf () berfungsi seperti yang dimaksudkan ...
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[])
daripada valueOf(Object)
. Perilaku valueOf(char[])
berbeda secara signifikan terhadap char[].toString()
. Namun demikian, jawaban ini bukan sesuai karena Anda memanggil kelebihan yang berbeda dengan pertanyaan yang ditanyakan.
Di bawah ini menunjukkan implementasi untuk java.lang.String.valueOf seperti yang dijelaskan dalam sumber untuk jdk8u25. Jadi sesuai komentar saya, tidak ada perbedaan. Itu panggilan "Object.toString". Untuk tipe primitif, ia membungkusnya dalam bentuk objeknya dan memanggil "toString" di atasnya.
Lihat di bawah:
/*
* 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
digunakan. Untuk objek yang menggantikan toString, saya pikir String.valueOf mungkin menyebutnya sebagai gantinya. Tidak yakin tentang bagian itu.