[Java] UnsupportedOperationException

ssunn·2024년 2월 13일
0

사이드 프로젝트

목록 보기
4/8

문제상황

블루밍 작업 중 골에 참여하는 참여자 리스트 관련 로직이 많아져 이를 Teams로 따로 뺐다. (이전 글 참고) 그런데 이 Teams의 경우 독립된 하나의 역할을 맡는 엔티티 클래스라고 보긴 어려웠다. 그래서 Teams의 생성자를 그대로 사용하기보다 생성 역할을 하는 팩토리 메서드를 사용하는 것이 어떻냐는 의견에 팩토리 메서드로 분리 작업을 수행했다.
리팩토링 도중 아래와 같은 에러를 마주하게 되었는데…

위의 에러를 좀 더 자세히 알아보자면

UnsupportedOperationException
불변 리스트의 변이: 만약 goalTeams가 불변 리스트로 처리된다면(예: 직렬화/역직렬화 또는 외부 요인으로 인해), 해당 리스트를 수정하려고 할 때 UnsupportedOperationException이 발생합니다. 리스트가 실제로 가변인지 확인하십시오.
출처: chatGPT

처음보는 에러라 매우 당황했다.

goalTeams를 받을 TeamsgoalTeams는 필드 선언부에서 new ArrayList<>()로 초기화 해줬기 때문에 가변상태였고, 그 이후로는 이 ArrayList에 추가할 뿐이라 에러가 날 곳이 없다고 생각했다. 문제는…. 생성자에 있었다.

Teams 생성 로직

private Teams(final List<GoalTeam> goalTeams) {
    this.goalTeams = goalTeams;
}

public static Teams create(final List<User> users, final Goal goal) {
    validateUsersSize(users);
    final List<GoalTeam> goalTeams = users.stream()
                                          .map(user -> new GoalTeam(user, goal))
                                          .toList();
    return new Teams(goalTeams);
}

이렇게 생성자에서 생성을 해준 이후에는 수정이 불가한 상태가 되어버린 것이다.

Teams를 생성할 때는 문제없이 잘 돌아가던 로직이었는데, 수정에서 문제가 발생했다.

기존 TeamsgoalTeams에 없는 사용자로 새로운 GoalTeam 객체들을 만들고, 이들을 stream().map().toList()로 받아 기존 TeamsgoalTeam에 추가해주려고 했는데 추가에서 문제가 생겼다.

해결방법

이유인 즉슨, this.goalTeamsnew ArrayList<>()로 초기화 했으나 생성자에서 파라미터로 받은 goalTeam을 그대로 할당해 기존 초기화가 의미가 없어졌으며, 파라미터로 받은 goalTeamstreamtoList 형태로 바꿔준 것이라 원소가 추가되거나 제거될 수 없다고 한다. 그러니까 stream().map().toList() 자체가 불변상태였던 것이다..

그래서 위의 생성자 로직을 다음과 같이 기존 리스트에 추가하는 식으로 바꿔주니 에러가 발생하지 않고 잘 돌아갔다.

private Teams(final List<GoalTeam> goalTeams) {
    this.goalTeams.addAll(goalTeams);
}

이렇게 또 하나 배워간다.. 자바 공부 좀 해야할 것 같다ㅎ

profile
BackEnd Developer

0개의 댓글

관련 채용 정보