개발 낙서장

[TIL] 내일배움캠프 15일차 - UnsupportedOperationException - 본문

Java/Sparta

[TIL] 내일배움캠프 15일차 - UnsupportedOperationException -

권승준 2024. 1. 15. 19:38

 

 

오늘의 학습 키워드📚

UnsupportedOperationException

  • UnsupportedOperationException은 RuntimeException의 한 종류로 지원되지 않은 작업을 요청할 때 발생하는 에러이다.

팀 프로젝트를 진행하던 도중 갑자기 예외가 발생했다. 예외가 발생하면 그냥 프로그램이 종료되게 해놨는데 원인을 몰라 예외 메세지를 찍어보며 디버깅을 했다.

로그를 찍어보니 예외 이름이 UnsupportedOperationException이었고 난생 처음 보는 예외였어서 검색을 해봤다.

보통 List를 다룰 때 많이 발생하는 예외라고 한다.

    // 과목 id를 key, 10회차에 대한 Score id의 List를 Value
    private Map<String, List<String>> scoreBySubject;

    public Student(String studentId, String studentName, List<String> mandatorySubjectList, List<String> choiceSubjectList) {
        this.studentId = studentId;
        this.studentName = studentName;
        this.studentState = "Green";

        scoreBySubject = new HashMap<>();

        this.mandatorySubjectList = mandatorySubjectList;
        for(String s : mandatorySubjectList) {
            scoreBySubject.put(s, List.of("0", "0", "0", "0", "0", "0", "0", "0", "0", "0"));
        }

        this.choiceSubjectList = choiceSubjectList;
        for(String s : choiceSubjectList) {
            scoreBySubject.put(s, List.of("0", "0", "0", "0", "0", "0", "0", "0", "0", "0"));
        }
    }

학생에 대한 정보를 담고 있는 Student 클래스의 일부이다. 과목 별 점수를 Map에 List로 관리하고 있으며 생성될 때 전부 0으로 초기화되게 해놨다.

여기서 List.of 부분 때문에 에러가 발생했는데

    // 해당 과목을 수강하고 있고 해당 과목의 회차에 대한 점수가 아직 등록되지 않았을 때
    public boolean addScoreBySubject(String subjectId, Score score) {
        if(scoreBySubject.containsKey(subjectId)) {
            if(scoreBySubject.get(subjectId).get(score.getScoreIndex() - 1).equals("0")) {
                scoreBySubject.get(subjectId).set(score.getScoreIndex() - 1, score.getScoreId());

                return true;
            }
        }

        return false;
    }

점수를 추가하는 메소드에서 해당 List의 값을 바꿔주는 set 메소드를 사용하고 있다.
하지만 List.of로 생성된 List는 불변의 값을 가진다.
즉 List.of로 생성했으면 삽입, 삭제, 수정의 작업이 일절 불가능하다.

따라서 해당 작업을 지원하지 않는데 시도했기 때문에 UnsupportedException이 발생해서 프로그램이 종료된 것이다.

    public Student(String studentId, String studentName, List<String> mandatorySubjectList, List<String> choiceSubjectList) {
        this.studentId = studentId;
        this.studentName = studentName;
        this.studentState = "Green";

        scoreBySubject = new HashMap<>();

        this.mandatorySubjectList = mandatorySubjectList;
        for(String s : mandatorySubjectList) {
            scoreBySubject.put(s, new ArrayList<>(List.of("0", "0", "0", "0", "0", "0", "0", "0", "0", "0")));
        }

        this.choiceSubjectList = choiceSubjectList;
        for(String s : choiceSubjectList) {
            scoreBySubject.put(s, new ArrayList<>(List.of("0", "0", "0", "0", "0", "0", "0", "0", "0", "0")));
        }
    }

그래서 생성자 부분을 바꿔줬는데, List.of로 생성한 리스트를 새로운 ArrayList로 값만 받아서 생성하게 되면 값의 변경에 자유로워진다.

앞으로 List.of를 사용할 때는 값의 참조나 확인의 작업만 필요할 때 사용해야겠다.

또한 List를 생성하는 방법으로 List.of 말고 Arrays.asList라는 방법도 있다고 한다.
Arrays.asList 방법은 set은 가능하지만 add와 remove는 불가능하다고 한다.


오늘의 회고💬

벌써 팀프로젝트 마무리 단계에 돌입했다. 팀원 분들이 열심히 해주셔서 너무 감사하고 오히려 내가 잘 하지 못한 것 같아서 아쉽다.

 

내일의 계획📜

내일은 팀 프로젝트 제출하는 날이다. 작성한 코드를 전부 취합해 정리하고 최종 리팩토링을 진행해야겠다.

Comments