String.valueOf () 대 Object.toString ()


132

자바에서의 차이가 String.valueOf(Object)Object.toString()? 이에 대한 특정 코드 규칙이 있습니까?


10
기본 유형에는 "toString"이 없습니다 String.valueOf. 사용됩니다. toString을 재정의하는 객체의 경우 String.valueOf가 대신 호출 할 수 있다고 생각합니다. 그래도 그 부분에 대해서는 확실하지 않습니다.
Brandon

@Brandon 당신은 맞습니다, 그것이 null먼저 확인한다는 것을 제외하고는 정확히 그렇게합니다 .
azurefrog

내가 생각하는 첫 번째 의견은 그것이 맞다면 가장 의미가 있다고 생각합니다. 대상이 기본 유형 인 특정 상황에서는 String.valueOf를 사용해야합니다.
Donato

답변:


177

에 따르면 자바 문서 , 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
이것이 가장 좋은 대답입니다. 코드가 아닌 javadoc을 읽고 의존하십시오. (코드는 Java의 버전 / 릴리스에 따라 원칙적으로 다를 수 있습니다.)
Stephen C

7
@Brandon-잘못되었습니다. javadoc을 무효화하는 방식으로 동작이 변경되는 경우에만 변경하면됩니다 . 1)이 방법에서 일어날 가능성은 ZERO입니다. 그들은 스펙의 변경을 보증하는 변경을하지 않을 것이며 , 만약 그렇다면 스펙을 변경할 입니다. 2) 내 조언을 무효화하지 않습니다. javadoc을 읽으면 문서화 된 동작이 변경되었음을 알 수 있습니다!
Stephen C

2
예외를 던지는 방법이 안전하지 않습니까? 일반적으로 코드에서 NullPointerException이 발생하면 일종의 좋은 일입니다. 현재 개발자에게는 좋지 않을 수도 있지만 ( "aww, 아니요, 이제 돌아가서 코드를 수정해야합니다") 오류가 발생했기 때문에 문제를 해결해야한다는 것을 알게되었습니다. 다른 방법으로 남겨두면 "null"을 사용자에게 직접 노출시키고 명시 적으로 확인하지 않으면 오류가 발생하지 않으므로 안전하지 않습니다.
Tim M.

1
분명히하기 위해 실제로 전화 할 수는 없습니다 String.valueOf(null).NPE입니다. null 인 객체에 대해서만 작동합니다.
Noumenon

1
그것은 설명이 아닙니다. 는 String.valueOf(null)사실로 확인 valueOf(char[])과부하. char[]보다 구체적인 유형 이기 때문 입니다 Object.
Stephen C

17

String.valueOf (Object)와 Object.toString ()의 차이점은 다음과 같습니다.

1) 문자열이 null이면

String.valueOf(Object)null 포인터 예외가 발생 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) 서명 :

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를 제공합니다.

과부하

그것은 밝혀 String.valueOf(null)(! 차이를주의) 하지 javadoc가에도 불구하고 ... NPE을 제공합니다. 설명이 모호합니다.

  1. 의 과부하에는 여러 가지가 String.valueOf있지만 여기에 관련된 두 가지가 있습니다 : String.valueOf(Object)String.valueOf(char[]).

  2. 이 식에서 는 할당이 모든 참조 유형과 호환 되므로 String.valueOf(null)두 과부하 모두 적용 가능null 합니다.

  3. 적용 가능한 과부하 가 둘 이상 있는 경우 JLS는 가장 특정한 인수 유형에 대한 과부하 가 선택 되었다고 말합니다 .

  4. 이후 char[]의 하위 유형입니다 Object, 그것은이다 더 구체적인 .

  5. 따라서 String.valueOf(char[])과부하가 호출됩니다.

  6. 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 합니까?)

참고 : 이것은 코드 규칙이 아닙니다. 그냥 상식 프로그래밍입니다. 어떤 문체 규칙이나 "모범 사례"교리를 따르는 것보다 코드가 올바른 것이 더 중요합니다 .


개인적인 의견 :

일부 개발자는 null에 대해 "방어"하는 나쁜 습관을 (IMO) 얻습니다. 따라서 널에 대한 많은 테스트와 널을 특수한 경우로 취급합니다. 아이디어는 NPE가 발생하는 것을 막는 것 같습니다.

나는 이것이 나쁜 생각이라고 생각합니다. 특히, 당신이 찾을 때 당신이하는 일 null이 왜 거기에 있었는지를 고려하지 않고 "좋은 것"을 시도 하는 것이 나쁜 생각이라고 생각합니다 null.

일반적으로 응용 프로그램이나 API 디자인에 매우 특별한 의미가 null없다면 처음에는 존재하지 않는 null것이 좋습니다. 따라서 많은 방어 코딩으로 NPE를 피하는 대신 NPE가 발생하도록 한 다음 NPE null를 트리거 한 예기치 않은 원인을 추적하고 수정하는 것이 좋습니다.

여기 어떻게 적용됩니까?

글쎄, 당신이 그것에 대해 생각하면 사용 하는 "좋은"방법 String.valueOf(obj) 있습니다. 피해야합니다. 위해 예기치 않은 상황이라면 objnull맥락에서, 그것을 사용하는 것이 좋습니다 obj.toString().


5

대부분 다른 답변에서 이미 언급되었지만 완전성을 위해 추가합니다.

  1. 프리미티브는- 클래스 .toString()의 구현이 아니므로 a 를 갖지 Object않으므로 사용할 String.valueOf수 있습니다.
  2. String.valueOf이다 주어진 객체 변환 할 null문자열을 "null", 반면 .toString()발생합니다 NullPointerException.
  3. 컴파일러는 String.valueOf비슷한 것을 사용할 때 기본적으로 String s = "" + (...);사용합니다. 그렇기 때문에 NPE가 아닌 Object t = null; String s = "" + t;String이 "null"됩니다. 편집 : 실제로 StringBuilder.append, not 을 사용합니다 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(AN입니다 StringInteger이 경우 캐스트)가 발생됩니다 ClassCastException.
  • 사용 String.valueOf하면 컴파일 T하는 Object동안 일반 을 볼 수 있으며 심지어는 신경 쓰지 않아도 Integer됩니다. 따라서 컴파일러가 무시 하는 Objectto 를 캐스팅합니다 Object. 그런 다음을 사용 하여 예상대로 String.valueOf(Object)결과 String를 얻습니다. 따라서 매개 변수가 내부적으로 매개 변수에 대한 String.valueOf(Object)작업을 수행 하더라도 .toString()캐스트를 건너 뛰고을 처리 하여의 사용으로 발생 Object하는 ClassCastException것을 피했습니다 .toString().

여기 String.valueOf.toString()여기의 추가 차이점을 언급 할 가치가 있다고 생각했습니다 .


마지막으로 JDK 1.2와 관련이 있었을 때 ("" + x)String.valueOf(x) 에 있었지만 컴파일 된 것이 더 복잡했지만 더 복잡한 것은 StringBuffer(우리는 없었습니다 StringBuilder).
Neil

4

String.valueOf(Object)그리고 Object.toString()말 그대로 같은 일이다.

당신의 구현을 살펴 가지고가는 경우에 한 String.valueOf (개체) , 당신은 볼 수 있습니다 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();
}

사실이 아니라면 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

argument가 null인 경우을 String.valueOf반환 "null"하지만을 Object.toString던집니다 NullPointerException. 이것이 유일한 차이점입니다.


0

두 메소드 사이에 한 가지 더 큰 차이점은 변환하려는 객체가 배열 일 때입니다.

Object.toString ()을 사용하여 배열을 변환하면 일종의 가비지 값 (@ 뒤에 배열의 해시 코드)이 나타납니다.

사람이 읽을 수있는 toString ()을 얻으려면 String.valueOf (char []);를 사용해야합니다. plz는이 메소드가 char 유형의 Array에만 작동한다는 점에 유의하십시오. 배열을 String으로 변환하기 위해 Arrays.toString (Object [])을 사용하는 것이 좋습니다.

두 번째 차이점은 객체가 null 인 경우 ValueOf ()는 문자열 "null"을 반환하지만 toString ()은 null 포인터 예외를 반환합니다.


안녕하세요 @Tom 이것은 모든 유형의 배열에 해당되지만 Arrays.toString (Object [])을 사용하는 경우 모든 유형의 배열을 문자열로 변환 할 수 있습니다.
chintan thakker

가비지 값을 반환하는 @Tom Object.toString ()은 모든 유형의 배열에 대해 true입니다 .String.valueOf (Array)는 char 유형의 배열에 대해서만 올바른 문자열을 제공합니다. 고마워요, 편집하겠습니다.
친 탄 thakker

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

설명은 실제로 전화 valueOf(char[])하기보다는 전화 하는 것 valueOf(Object)입니다. 의 동작은와 valueOf(char[])크게 다릅니다 char[].toString(). 그러나 어느 쪽이든,이 답변은 질문이 요구하는 것과 다른 과부하를 호출하기 때문에 제안 되지 않습니다 .
Stephen 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.