“SomeType @ 2f92e0f4”를받지 않고 Java 객체를 어떻게 인쇄합니까?


300

다음과 같이 정의 된 클래스가 있습니다.

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

클래스의 인스턴스를 인쇄하려고했습니다.

System.out.println(myPerson);

그러나 나는 다음과 같은 결과를 얻었다 : com.foo.Person@2f92e0f4.

Person객체 배열을 인쇄하려고 할 때도 비슷한 일이 발생했습니다 .

Person[] people = //...
System.out.println(people); 

나는 출력을 얻었다 : [Lcom.foo.Person;@28a418fc

이 결과는 무엇을 의미합니까? 본인의 이름이 포함되도록이 출력을 어떻게 변경합니까? 객체 컬렉션을 어떻게 인쇄합니까?

참고 :이 주제에 대한 정식 Q & A를위한 것입니다.


1
GSON 라이브러리를 사용 하여 객체를 json으로 또는 그 반대로 변환 할 수 있습니다 . 디버깅에 매우 유용합니다.
Ashish Rawat

답변:


403

배경

모든 Java 객체에는 toString()객체를 인쇄하려고 할 때 호출되는 메소드가 있습니다.

System.out.println(myObject);  // invokes myObject.toString()

이 메소드는 Object클래스 (모든 Java 오브젝트의 수퍼 클래스 )에 정의되어 있습니다. 이 Object.toString()메소드는 클래스 이름, @심볼 및 오브젝트 의 해시 코드 로 구성된 상당히보기 흉한 문자열 을 16 진수 로 리턴합니다 . 이에 대한 코드는 다음과 같습니다.

// Code of Object.toString()
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

com.foo.MyType@2f92e0f4따라서 다음 과 같은 결과를 설명 할 수 있습니다.

  • com.foo.MyType -클래스의 이름. 즉 클래스가 MyType패키지에있다 com.foo.
  • @ -문자열을 결합
  • 2f92e0f4 객체의 해시 코드

배열 클래스의 이름은 약간 다르게 보입니다 Class.getName(). 에 대한 Javadocs에 잘 설명되어 있습니다 . 예를 들어 다음을 [Ljava.lang.String의미합니다.

  • [- (대향 같은 단일 차원 어레이 [[또는 [[[등)
  • L -배열은 클래스 또는 인터페이스를 포함
  • java.lang.String -배열 내의 객체의 형태

출력 사용자 정의

당신이 전화 뭔가 다른를 인쇄하려면 System.out.println(myObject)다음을 수행해야 오버라이드 (override)toString() 자신의 수업 방법을. 다음은 간단한 예입니다.

public class Person {

  private String name;

  // constructors and other methods omitted

  @Override
  public String toString() {
    return name;
  }
}

이제를 인쇄하면 Person이름이 아닌 이름이 표시 com.foo.Person@12345678됩니다.

마음에 베어 toString()그냥 하나의 방법으로 개체에 대한 문자열로 변환 할 수 있습니다. 일반적으로이 출력은 객체를 명확하고 간결하게 설명해야합니다. toString()우리 Person수업에 더 좋을 수도 있습니다 :

@Override
public String toString() {
  return getClass().getSimpleName() + "[name=" + name + "]";
}

예를 들어 Person[name=Henry]. 디버깅 / 테스트에 유용한 데이터입니다.

객체의 한 측면에만 초점을 맞추거나 많은 재즈 형식을 포함하려면 대신 별도의 방법을 정의하는 것이 좋습니다 (예 :) String toElegantReport() {...}.


출력 자동 생성

많은 IDEtoString() 가 클래스의 필드를 기반으로 메소드 자동 생성을 지원합니다 . 예를 들어 EclipseIntelliJ 용 문서를 참조하십시오 .

널리 사용되는 여러 Java 라이브러리도이 기능을 제공합니다. 몇 가지 예는 다음과 같습니다.


객체 그룹 인쇄

그래서 당신은 toString()당신의 수업에 좋은 곳 을 만들었습니다 . 해당 클래스가 배열 또는 컬렉션에 배치되면 어떻게됩니까?

배열

객체 배열이있는 경우 호출 Arrays.toString()하여 배열의 내용을 간단하게 표현할 수 있습니다 . 예를 들어,이 Person객체 배열을 고려하십시오 .

Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));

// Prints: [Fred, Mike]

참고 : 이것은 Arrays 클래스에서 호출 된 정적 메소드 toString()에 대한 호출 이며 위에서 논의 한 것과 다릅니다.

다차원 배열 이있는 경우 Arrays.deepToString()동일한 종류의 출력을 달성하는 데 사용할 수 있습니다 .

컬렉션

대부분의 컬렉션은 .toString()모든 요소 에 대한 호출 을 기반으로 예쁜 출력을 생성합니다 .

List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));    
System.out.println(people);

// Prints [Alice, Bob]

따라서 toString()위에서 설명한대로 목록 요소가 멋지게 정의되도록해야합니다 .


return String.format( getClass().getSimpleName() + "[ name=%s ]", name);그리고 실제로 대신 namegetter를 사용해야합니다 getName()(하지만 getter는 Person 클래스에서 생략되었습니다). getter가 사용 된 경우 ...return String.format( getClass().getSimpleName() + "[ name=%s ]", getName());
CrandellWS

Java 파일에 두 개의 클래스가있는 경우 public A.java public class A {} class B {} ------ C.java public class C {A a = new A ( ); }
yatinbc

오버로드 된 버전이 Arrays.toString()있으므로 프리미티브 배열에도 사용할 수 있습니다 ( int[], double[]). 또한 Arrays.deepToString()다차원 배열의 프리미티브를 잘 처리합니다.
Ole VV

1
@ MasterJoe2 확실하지 않을 수도 있습니다. 아마도 음수 값을 문자열로 인코딩하려고하면 추악한 것처럼 보일까요?
던컨 존스

55

아파치는 문자열을 얻는 기능을 제공하는 더 나은 유틸리티 클래스를 제공한다고 생각합니다.

ReflectionToStringBuilder.toString(object)

5
이것은 클래스를 편집 할 필요가 없다는 장점이 있으며 때로는 불가능합니다. 그러나 중첩 된 객체를 어떻게 재귀 적으로 인쇄 할 수 있습니까?
lukas84

34

Java의 모든 클래스에는 toString()기본적으로 메소드 가 있으며, 이 클래스의 일부 오브젝트를에 전달하면 호출됩니다 System.out.println(). 기본적으로이 호출은 해당 객체의 className @ hashcode를 반환합니다.

{
    SomeClass sc = new SomeClass();
    // Class @ followed by hashcode of object in Hexadecimal
    System.out.println(sc);
}

다른 출력을 얻기 위해 클래스의 toString 메소드를 대체 할 수 있습니다. 이 예를 참조하십시오

class A {
    String s = "I am just a object";
    @Override
    public String toString()
    {
        return s;
    }
}

class B {
    public static void main(String args[])
    {
        A obj = new A();
        System.out.println(obj);
    }
}

3
이것은 잘 넣어 짧은 대답하지만, 영업 이익은 점점 이유를 명확히하는 것입니다 [Lcom.foo.Person;@28a418fc의 출력입니다 : 출력으로 toString()도, 방법,하지만 유형에 대한 실행시에 생성 된 클래스에서 구현되는 하나 Person[],하지 Person(참조 stackoverflow.com/a/8546532/1542343 ).
gvlasov

이 출력은 package.Class@Hashcode를 의미합니다. 기본 toString () 메소드에는 리턴 유형이 있습니다. 클래스 이름과 함께 16 진수 형식으로 해시 코드를 반환하는 Object.hasCode () 또는 이와 유사한 반환 문을 반환합니다.
Pankaj Manali

14

Eclipse에서 클래스로 이동하여 마우스 오른쪽 단추로 클릭-> 소스-> 생성하십시오 toString().

toString()메소드 를 대체하고 해당 클래스의 오브젝트를 인쇄합니다.


10

Java 객체를 JSON 문자열로 직렬화 해제하기 위해 GSON 을 사용하는 유틸리티 기능을 선호 합니다.

/**
 * This class provides basic/common functionalities to be applied on Java Objects.
 */
public final class ObjectUtils {

    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();

    private ObjectUtils() {
         throw new UnsupportedOperationException("Instantiation of this class is not permitted in case you are using reflection.");
    }

    /**
     * This method is responsible for de-serializing the Java Object into Json String.
     *
     * @param object Object to be de-serialized.
     * @return String
     */
    public static String deserializeObjectToString(final Object object) {
        return GSON.toJson(object);
    }
}

return Gson.toJson(object);그렇지 않으면 완벽하게 작동 해야합니다 .
Nakrule

그게 다야.
Agam

5

intellij에서는 alt + inset을 누르고 toString ()을 선택하여 toString 메소드를 자동 생성 할 수 있습니다.

public class test  {
int a;
char b;
String c;
Test2 test2;

@Override
public String toString() {
    return "test{" +
            "a=" + a +
            ", b=" + b +
            ", c='" + c + '\'' +
            ", test2=" + test2 +
            '}';
 }
}

보시다시피, 클래스의 여러 속성을 연결하여 문자열을 생성합니다. 프리미티브의 경우 값을 인쇄하고 참조 유형의 경우 클래스 유형을 사용합니다 (이 경우 Test2의 문자열 메소드).


4

기본적으로 Java의 모든 Object toString()에는 ObjectType @ HashCode를 출력하는 메소드가 있습니다.

더 의미있는 정보를 원한다면 toString()클래스 의 메소드 를 재정의해야합니다 .

public class Person {
  private String name;

  // constructor and getter/setter omitted

  // overridding toString() to print name
  public String toString(){
     return name;  
  }
}

이제를 사용하여 사람 개체를 인쇄하면 System.out.prtinln(personObj); 인쇄하면 클래스 이름과 해시 코드 대신 사람의 이름이 인쇄됩니다.

두 번째 경우 배열을 인쇄하려고 할 때 [Lcom.foo.Person;@28a418fc배열 유형을 인쇄 하고 해시 코드입니다.


사람 이름을 인쇄하려면 여러 가지 방법이 있습니다.

각 사람을 반복하고 인쇄하는 자신의 기능을 작성할 수 있습니다.

void printPersonArray(Person[] persons){
    for(Person person: persons){
        System.out.println(person);
    }
}

Arrays.toString ()을 사용하여 인쇄 할 수 있습니다. 이것은 나에게 가장 간단한 것 같습니다.

 System.out.println(Arrays.toString(persons));
 System.out.println(Arrays.deepToString(persons));  // for nested arrays  

java 8 방식으로 인쇄 할 수 있습니다 (스트림 및 메소드 참조 사용).

 Arrays.stream(persons).forEach(System.out::println);

다른 방법도있을 수 있습니다. 도움이 되었기를 바랍니다. :)


3

Person의 객체를 직접 인쇄하면 ClassName@HashCode 하면 코드에 .

귀하의 경우 com.foo.Person@2f92e0f4에는 인쇄되고 있습니다. Person객체가 속한 클래스는 어디에 2f92e0f4있고 객체의 hashCode입니다.

public class Person {
  private String name;

  public Person(String name){
  this.name = name;
  }
  // getter/setter omitted

   @override
   public String toString(){
        return name;
   }
}

이제 객체를 사용하려고 Person하면 이름이 인쇄됩니다.

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}

2

Object 클래스 (Java의 모든 클래스의 부모 클래스)를 보면 toString () 메소드 구현은 다음과 같습니다.

    public String toString() {
       return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

Java로 객체를 인쇄 할 때마다 toString ()이 호출됩니다. toString ()을 재정의하면 메서드가 다른 Object 클래스 메서드 호출을 호출합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.