Чи є в Java різниця між String.valueOf(Object)і Object.toString()? Чи існує для них певна норма коду?
nullспочатку.
Чи є в Java різниця між String.valueOf(Object)і Object.toString()? Чи існує для них певна норма коду?
nullспочатку.
Відповіді:
Відповідно до документації Java , String.valueOf()повертає:
якщо аргумент є
null, то рядок дорівнює"null"; в іншому випадкуobj.toString()повертається значення.
Тож насправді не повинно бути різниці, крім додаткового виклику методу.
Крім того, у випадку Object#toString, якщо екземпляр є null, 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. Він працює лише для об’єктів, які є недійсними.
String.valueOf(null)Фактично вирішує до valueOf(char[])перевантаження. Це тому, що char[]є більш специфічним типом, ніж Object.
Різниці між String.valueOf (Object) та Object.toString () є:
1) Якщо рядок є нульовим,
String.valueOf(Object)повернеться null, тоді як Object::toString()викине нульовий виняток вказівника.
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) Підпис:
метод valueOf () класу String є статичним. тоді як метод toString () класу String не є статичним.
Нижче подано підпис або синтаксис методу 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.
Виявляється, що String.valueOf(null)(зверніть увагу на різницю!) Робить дати NPE ... незважаючи на Javadoc. Пояснення незрозуміле:
Існує ряд перевантажень String.valueOf, але тут є два, що є актуальними: String.valueOf(Object)і String.valueOf(char[]).
У вираженні String.valueOf(null), обидві ці перевантаження можуть застосовуватися , так як nullце призначення сумісний з будь-яким посилальним типом.
Коли є дві або більше застосовних перевантажень, JLS каже, що вибирається перевантаження для найбільш конкретного типу аргументу.
Оскільки char[]є підтипом Object, він є більш специфічним .
Тому String.valueOf(char[])викликається перевантаження.
String.valueOf(char[])кидає 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) "захищатись" від нулів. Тож ви бачите безліч тестів на нулі та трактуєте нулі як особливі випадки. Здається, ідея заважає NPE відбуватися.
Я думаю, що це погана ідея. Зокрема, я вважаю, що це погана ідея, якщо те, що ти робиш, коли ти знайдеш, - nullце спробувати "зробити добро" ... без огляду на те, чому там nullсталося.
Взагалі, краще уникати nullперебування там у першу чергу ... якщо тільки це не nullмає дуже специфічного значення у вашій програмі чи дизайні API. Отже, замість того, щоб уникати NPE з великою кількістю оборонних кодувань, краще дозволити NPE статися, а потім відстежити та виправити джерело несподіваного, nullщо викликало NPE.
То як це стосується тут?
Ну, якщо ви подумаєте над цим, використання String.valueOf(obj) може бути способом "зробити добро". Цього слід уникати. Якщо несподівано для objбути nullв контексті, то краще використовувати obj.toString().
Більшість вже згадувалися іншими відповідями, але я просто додаю це для повноти:
.toString()оскільки вони не є реалізацією Objectкласу, тому String.valueOfїх можна використовувати лише.String.valueOfперетворить заданий об'єкт, що знаходиться nullу String "null", тоді як .toString()кине a NullPointerException.String.valueOfза замовчуванням, коли використовується щось подібне String s = "" + (...);. Ось чому Object t = null; String s = "" + t;це призведе до рядка "null", а не до NPE. 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: classjava.lang.Stringне може бути передано до класуjava.lang.Integer
Щодо того, чому я можу посилатися на це окреме питання та його відповіді . Якщо коротко, однак:
.toString()він спочатку компілювати і оцінювати об'єкт, в якому приведення до T(який є Stringдо Integerвідлитий в даному випадку) призведе до ClassCastException.String.valueOfвін побачить загальне, Tяк Objectпід час компіляції, і навіть не піклується про те, щоб воно було Integer. Таким чином, він додасть Objectдо Object(що компілятор просто ігнорує). Тоді він буде використовуватись String.valueOf(Object), в результаті чого, Stringяк очікувалося. Тож, хоча String.valueOf(Object)воля буде робити .toString()параметр внутрішньо, ми вже пропустили команду та її обробляємо як an Object, тому ми уникнули того, ClassCastExceptionщо відбувається з використанням .toString().Просто подумав, що варто згадати цю додаткову різницю між String.valueOfі .toString()тут.
("" + x)зібраного String.valueOf(x), але все, що складніше, було використано StringBuffer(у нас тоді не було StringBuilder).
String.valueOf(Object)і Object.toString()буквально одне і те ж.
Якщо ви подивитеся на реалізацію String.valueOf (Object) , ви побачите, що String.valueOf(Object)це в основному лише нульове виклик toString()відповідного об'єкта:
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();
}
Найголовніша відмінність - це те, як вони обробляють нульові посилання String.
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
Є ще одна основна відмінність двох методів, коли об’єкт, який ми перетворюємо, - це масив.
Перетворюючи масив за допомогою Object.toString (), ви отримаєте якесь значення сміття (@ з подальшим хеш-кодом масиву).
Щоб отримати зрозумілий для людини toString (), ви повинні використовувати String.valueOf (char []); Зауважте, що цей метод працює лише для масиву типу char. Я б рекомендував використовувати Arrays.toString (Object []) для перетворення масивів у String.
Друга відмінність полягає в тому, що коли об'єкт є null, ValueOf () повертає String "null", тоді як toString () повертає виключення null pointer.
Я не можу точно сказати, в чому різниця, але, здається, є різниця при роботі на рівні байтів. У наступному сценарії шифрування 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(). Але так чи інакше, ця відповідь не по приводу , тому що ви викликаєте іншу перевантаження в один Питання запитує о.
Нижче показано реалізацію для java.lang.String.valueOf, як описано у джерелі для jdk8u25. Отже, на мій коментар, різниці немає. Він називає "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 може зателефонувати до цього. Не впевнений у цій частині, хоча.