Java'da String.valueOf(Object)ve arasında herhangi bir fark var Object.toString()mı? Bunlar için özel bir kod kuralı var mı?
nullilk önce kontrol etmesi dışında .
Java'da String.valueOf(Object)ve arasında herhangi bir fark var Object.toString()mı? Bunlar için özel bir kod kuralı var mı?
nullilk önce kontrol etmesi dışında .
Yanıtlar:
Göre Java belgeleri , String.valueOf()döner:
argüman ise
null, o zaman bir dizge eşittir"null"; aksi takdirde değeriobj.toString()döndürülür.
Bu nedenle, ek bir yöntem çağrısı dışında gerçekten bir fark olmamalıdır.
Ayrıca, Object#toStringörnek olması durumunda null, a NullPointerExceptionatılır, bu yüzden tartışmalı bir şekilde daha az güvenlidir .
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)arayamazsınız, bu bir NPE'dir. Yalnızca boş olan nesneler için çalışır.
String.valueOf(null)Aslında olarak çözümlenir valueOf(char[])aşırı. Bunun nedeni char[], daha özel bir tür olmasıdır Object.
String.valueOf (Object) ve Object.toString () arasındaki farklar şunlardır:
1) string boş ise,
String.valueOf(Object)dönecek null, oysa Object::toString()boş bir işaretçi istisnası atacak.
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) İmza:
String sınıfının valueOf () yöntemi statiktir. oysa String sınıfının toString () yöntemi statik değildir.
Dizenin valueOf () yönteminin imzası veya sözdizimi aşağıda verilmiştir:
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)
Dizenin toString()yönteminin imzası veya sözdizimi aşağıda verilmiştir:
public String toString()
Java'da, String.valueOf (Object) ve Object.toString () arasında herhangi bir fark var mı?
Evet. (Ve dahası, aşırı yüklemeyi düşünürseniz!)
Olarak javadoc açıklar String.valueOf((Object) null)ile özel bir durum olarak kabul edilir valueOfbir yöntem ve değer "null"iade edilir. Aksine, null.toString()size sadece bir NPE verecektir.
O çıkıyor String.valueOf(null)(! Farka dikkat) yapar javadoc rağmen ... Bir NPE ver. Açıklama belirsiz:
Çok sayıda aşırı yükleme var String.valueOf, ancak burada ilgili olan iki tane var: String.valueOf(Object)ve String.valueOf(char[]).
İfadede String.valueOf(null), atama herhangi bir referans tipiyle uyumlu olduğundan , bu aşırı yüklerin her ikisi de uygulanabilirnull .
İki veya daha fazla uygulanabilir aşırı yük olduğunda, JLS, en spesifik bağımsız değişken türü için aşırı yüklemenin seçildiğini söyler .
Yana char[]bir alt tipi olan Object, öyle daha spesifik .
Bu nedenle String.valueOf(char[])aşırı yükleme denir.
String.valueOf(char[])argümanı boş bir diziyse bir NPE atar. Aksine String.valueOf(Object), nullözel bir durum olarak ele alınmaz .
( Çağrısı javap -colan bir yöntemin kodunu incelemek için kullanarak bunu doğrulayabilirsiniz String.valueOf(null). Çağrı için kullanılan aşırı yüklemeyi gözlemleyin.)
Başka bir örnek, valueOf(char[])aşırı yükteki farkı daha da net bir şekilde göstermektedir:
char[] abc = new char[]('a', 'b', 'c');
System.out.println(String.valueOf(abc)); // prints "abc"
System.out.println(abc.toString()); // prints "[C@...."
Bunlar için özel bir kod kuralı var mı?
Hayır.
Kullanmakta olduğunuz bağlamın gereksinimlerine en uygun olanı kullanın. ( Çalışmak için biçimlendirmeye ihtiyacınız varnull mı?)
Not: Bu bir kod kuralı değildir. Bu sadece sağduyu programlamasıdır. Kodunuzun doğru olması, bazı biçimsel kuralları veya "en iyi uygulama" dogmaları izlemekten daha önemlidir .
Kişisel görüş:
Bazı geliştiriciler (IMO) boşlara karşı "savunma" gibi kötü bir alışkanlık edinirler. Böylece, boş değerler için çok sayıda test görüyorsunuz ve boş değerleri özel durumlar olarak değerlendiriyorsunuz. Fikir, NPE'nin olmasını engelliyor gibi görünüyor.
Bunun kötü bir fikir olduğunu düşünüyorum. Özellikle, a'yı bulduğunuzda yaptığınız şeyin null, neden orada olduğunu düşünmeden ... "iyiye gitmeye" çalışmaksa ... kötü bir fikir olduğunu düşünüyorum null.
Genel olarak, nullilk etapta orada olmaktan kaçınmak daha iyidir ... nulluygulamanızda veya API tasarımınızda çok özel bir anlamı yoksa. Bu nedenle, çok sayıda savunma kodlamasıyla NPE'den kaçınmak yerine, NPE'nin gerçekleşmesine izin vermek ve ardından nullNPE'yi tetikleyen beklenmedik kaynağın izini sürmek ve düzeltmek daha iyidir .
Peki bu burada nasıl geçerli?
Peki, düşünürseniz, kullanmak "iyileştirmenin" bir yolu String.valueOf(obj) olabilir . Bundan kaçınılması gerekir. Bağlamda objolması beklenmiyorsa null, kullanmak daha iyidir obj.toString().
Birçoğundan başka cevaplardan bahsedilmişti, ancak ben sadece bütünlük için ekliyorum:
.toString()bir Object-class uygulaması olmadıklarından, sadece String.valueOfkullanılabilirler.String.valueOfbelirli bir nesneyi nullString'e dönüştürecek "null", oysa .toString()bir NullPointerException.String.valueOfbenzeri bir String s = "" + (...);şey kullanıldığında varsayılan olarak kullanacaktır . Bu nedenle Object t = null; String s = "" + t;, "null"NPE ile değil , Dize ile sonuçlanacaktır . StringBuilder.append, değil String.valueOf. Bu yüzden burada söylediklerimi görmezden gelin.Bunların yanı sıra, burada bir kullanım örneği aslında String.valueOfve .toString()farklı sonuçlar vardır:
Diyelim ki bunun gibi genel bir yöntemimiz var:
public static <T> T test(){
String str = "test";
return (T) str;
}
Ve biz bir ile arayacağım Integerböyle türü: Main.<Integer>test().
Bir String oluşturduğumuzda String.valueOfiyi çalışıyor:
String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);
Bu testSTDOUT'a çıktı verecektir .
Bununla .toString()birlikte, işe yaramaz:
String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);
Bu, aşağıdaki hataya neden olur:
java.lang.ClassCastException: sınıfjava.lang.Stringsınıfa dönüştürülemezjava.lang.Integer
Nedenine gelince, bu ayrı soruya ve cevaplarına başvurabilirim . Kısacası, ancak:
.toString()ilk derlemek ve döküm nesnesini değerlendirecek T(bir olduğu Stringiçin Integer, bu durumda döküm) neden olur ClassCastException.String.valueOfjeneriği derleme sırasındaki Tgibi görür Objectve bir Integer. Böylece bir Objectto Object(derleyicinin görmezden geldiği) atacaktır . Daha sonra kullanacak ve beklendiği gibi String.valueOf(Object)a sonucunu verecektir String. Yani String.valueOf(Object)will .toString(), dahili olarak parametre üzerinde bir yapsa da, atlamayı zaten atladık ve bir gibi muamele Objectgördük, bu yüzden ClassCastExceptionkullanımıyla meydana gelenlerden kaçındık .toString().Sadece buradaki String.valueOfve arasındaki bu ek farktan bahsetmeye değer olduğunu düşündüm .toString().
("" + x)derlenmişti String.valueOf(x), ama daha karmaşık olan herhangi bir şey a kullanıyordu StringBuffer( StringBuildero zamanlar sahip değildik ).
String.valueOf(Object)ve Object.toString()kelimenin tam anlamıyla aynı şeydir.
String.valueOf (Object) uygulamasına bakarsanız, bunun String.valueOf(Object)temelde toString()uygun nesnenin boş güvenlikli bir çağrısı olduğunu göreceksiniz :
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();
}
En önemli fark, boş Dize referanslarını işleme şekilleridir.
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
İki yöntem arasında önemli bir fark daha var, dönüştürdüğümüz nesnenin bir dizi olması.
Object.toString () kullanarak bir diziyi dönüştürdüğünüzde, bir tür çöp değeri (@ ardından dizi hashcode'u) elde edersiniz.
İnsan tarafından okunabilir bir toString () elde etmek için String.valueOf (char []) kullanmanız gerekir; plz, bu yöntemin yalnızca char türündeki Array için çalıştığını unutmayın. Dizileri String'e dönüştürmek için Arrays.toString (Object []) kullanmanızı tavsiye ederim.
İkinci fark, nesne null olduğunda, ValueOf () bir String "null" döndürürken, toString () null işaretçi istisnası döndürür.
Farkın ne olduğunu tam olarak söyleyemem ama bayt seviyesinde çalışırken bir fark var gibi görünüyor. Aşağıdaki şifreleme senaryosunda Object.toString (), şifresi çözülemeyen bir değer üretirken String.valueOf () amaçlandığı gibi çalıştı ...
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[])yerine aradığınızdır valueOf(Object). Davranışı valueOf(char[])önemli ölçüde farklıdır char[].toString(). Ancak her iki durumda da, bu cevap uygun değildir çünkü Sorunun sorduğu sorudan farklı bir aşırı yükleme çağırıyorsunuz.
Aşağıda, jdk8u25 için kaynakta açıklandığı gibi java.lang.String.valueOf için uygulama gösterilmektedir. Yani benim yorumuma göre, hiçbir fark yok. "Object.toString" çağırır. İlkel türler için, onu nesne biçiminde sarar ve üzerinde "toString" çağırır.
Aşağıya bakınız:
/*
* 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.valueOfnedenle kullanılır. ToString'i geçersiz kılan nesneler için String.valueOf'un bunu çağırabileceğini düşünüyorum. Yine de o kısımdan emin değilim.