"SomeType @ 2f92e0f4"없이 Java 개체를 인쇄하려면 어떻게해야합니까?
다음과 같이 정의 된 클래스가 있습니다.
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입니다.
답변
배경
모든 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
객체의 해시 코드.
배열 클래스의 이름은 약간 다르게 보이며 .NET 용 Javadocs에 잘 설명되어 있습니다 Class.getName()
. 예를 들어 다음을 [Ljava.lang.String
의미합니다.
[
-1 차원 배열 ([[
또는 반대[[[
)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() {...}
.
출력 자동 생성
많은 IDE 는 toString()
클래스의 필드를 기반으로 메서드 자동 생성을 지원합니다 . 예를 들어 Eclipse 및 IntelliJ 문서를 참조하십시오 .
여러 인기있는 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()
위에서 설명한대로 목록 요소가 멋지게 정의되도록해야합니다 .
아파치가 문자열을 얻는 기능을 제공하는 더 나은 유틸리티 클래스를 제공한다고 생각합니다.
ReflectionToStringBuilder.toString(object)
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);
}
}
Eclipse에서 클래스로 이동하여 마우스 오른쪽 버튼으로 클릭-> 소스-> 생성 toString()
;
toString()
메서드 를 재정의하고 해당 클래스의 개체를 인쇄합니다.
GSON 을 사용 하여 Java 개체를 JSON 문자열로 역 직렬화 하는 유틸리티 함수를 사용하는 것을 선호 합니다.
/**
* 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);
}
}
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 +
'}';
}
}
보시다시피, 클래스의 여러 속성을 연결하여 String을 생성합니다. 프리미티브의 경우 값을 인쇄하고 참조 유형의 경우 클래스 유형을 사용합니다 (이 경우 Test2의 문자열 메서드).
기본적으로 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);
다른 방법도있을 수 있습니다. 도움이 되었기를 바랍니다. :)
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());
}
}
Object 클래스 (Java의 모든 클래스의 상위 클래스)를 보면 toString () 메소드 구현은 다음과 같습니다.
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Java에서 객체를 인쇄 할 때마다 toString ()이 호출됩니다. 이제 toString ()을 재정의하면 메서드가 다른 Object 클래스 메서드 호출을 호출 할 것입니다.
나는 이것을 Jackson
Spring 5에서 사용할 수 있었다 . 객체에 따라 Jackson은 모든 경우에 작동하지 않을 수있다.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
ObjectMapper mapper = new ObjectMapper();
Staff staff = createStaff();
// pretty print
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(staff);
System.out.println("-------------------------------------------------------------------")
System.out.println(json);
System.out.println("-------------------------------------------------------------------")
출력은 다음과 같습니다.
-------------------------------------------------------------------
{
"id" : 1,
"internalStaffId" : "1",
"staffCms" : 1,
"createdAt" : "1",
"updatedAt" : "1",
"staffTypeChange" : null,
"staffOccupationStatus" : null,
"staffNote" : null
}
-------------------------------------------------------------------
여기를 사용하는 더 많은 예Jackson
시도해 볼 GSON
수도 있습니다. 다음과 같아야합니다.
Gson gson = new Gson();
System.out.println(gson.toJson(objectYouWantToPrint).toString());