@TOString 과 @TOString.Exclude에 대해서

buffet_psi·2023년 4월 10일
0

sprint_basic

목록 보기
5/6

@TOString
Lombok 라이브러리에서 제공하는 어노테이션으로, 클래스나 필드에 적용하여 toString()메서드를 자동으로 생성해주는 어노테이션이다.
(디버깅 or 로깅을 간편하게 할 수 있다.)

예를 들어)
사람클래스에는 이름과 나이가 있다. 이때 나이와 이름을 문자열의 형태로 받고싶다면

import lombok.ToString;

@ToString
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

이렇게 @ToString를 이용하여 System.out.println(student);한다면 사람의 이름과 나이에 대한 문자열을 출력 받을 수 있다.

하지만 이번 포스팅에서 이야기하고 싶은것은 아래의 예제이다.
문제) 회사라는 클래스와 노동자라는 클래스가 있다. 메인에서는 buffet라는 회사에 17살의 폴이라는 노동자를 추가한뒤 이름과 나이의 정보를 문자열로 출력받고 싶어한다. 이때 개발자 A는 아래의 코드를 작성했는데 출력 결과는 어떻게 될까?

import lombok.ToString;

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        Company company = new Company();
        company.name = "buffet";

        Worker worker = new Worker();
        worker.age = 17;
        worker.name = "폴";
        worker.companyName = company; // 이 학생의 담당 선생님 세팅

        company.addWorkers(worker);//1번
        System.out.println(worker);//2번
    }
}
@ToString
class Company {
    public List<Worker> workers = new ArrayList<>();//3번
    public String name;

    public void addWorkers(Worker worker) {
        workers.add(worker);
    }
}

@ToString
class Worker {
	public Company companyName;//4번
    public int age;
    public String name;
}

정답은 올바르게 작동하지 않고 무한 루프 에러가 발생할 것이다. 왜일까??

이유
==> @ToString 애노테이션이 Worker 클래스에서 Company 필드를 출력하고, Company 클래스에서는 Worker 필드를 출력하는데, 이 두 필드가 서로를 참조하고 있기 때문이다. 따라서, toString() 메서드를 호출할 때 무한 루프가 발생하게 되어 StackOverflowError가 발생합니다.
(더 쉽게 말해서)
1번코드에서 Company에 worker를 추가하였다. 그리고 2번에서 문자열로 출력을 요청하면
1. Worker클래스로 이동해서 바로 첫번째 줄에있는 4번코드를 확인한다
2. 4번코드를 문자열로 참조하기위해서 Company클래스로간다
3. Company클래스에서는 List에 담겨있는 Woker타입을 문자열로 출력하기위해서 다시 Worker클래스로간다
4. 4번코드를 문자열로 참조하기위해서 Company클래스로간다
5. Company클래스에서는 List에 담겨있는 Woker타입을 문자열로 출력하기위해서 다시 Worker클래스로간다
... 이렇게 2번과 3번과정을 계속해서 반복하게 된다는 것이다. 그러면 무한 루프가 발생하고 StackOverflowError가 발생하게된다.

그러면 해결방법은? @ToString.Exclude 어노테이션을 workes 필드에 추가하여 toString() 메소드에서 제외시켜주고, Work 클래스에서도 @ToString.Exclude 어노테이션을 company 필드에 추가하여 제외시켜주면 됩니다.

import lombok.ToString;

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        Company company = new Company();
        company.name = "buffet";

        Worker worker = new Worker();
        worker.age = 17;
        worker.name = "폴";
        worker.companyName = company; // 이 학생의 담당 선생님 세팅

        company.addWorkers(worker);//1번
        System.out.println(worker);//2번
    }
}
@ToString
class Company {
	@ToString.Exclude // 여기에만 있어도 되고
    public List<Worker> workers = new ArrayList<>();//3번
    public String name;

    public void addWorkers(Worker worker) {
        workers.add(worker);
    }
}

@ToString
class Worker {
	@ToString.Exclude // 여기에만 있어도 되고
	public Company companyName;//4번
    public int age;
    public String name;
}
profile
노력과효율!

0개의 댓글