반응형
이슈
'toBoardInfo(Page<Board>, List<Status>)' clashes with 'toBoardInfo(Page<Like>, List<Status>)'; both methods have same erasure
👉 동일한 자료형을 반환하는 메서드 오버로딩을 구현하는데 문제가 발생했다.
자바에서는 메서드 오버라이딩과 오버로딩을 통해 다형성을 구현할 수 있다.
메서드 오버라이딩이란
- 부모 클래스가 가지고 있는 메서드를 자식 클래스에서 동일한 메서드 이름, 매개변수 타입 및 개수로 재정의하는 것을 의미한다.
- 상속 관계에서 발생하며, 자식 클래스에서 부모 클래스의 메서드를 재정의하여 자식 클래스의 특정한 동작을 수행할 수 있다.
메서드 오버로딩이란
- 같은 클래스 내에서 메서드 이름은 같지만, 매개변수의 타입, 순서, 개수가 다른 여러 개의 메서드를 선언하는 것을 의미한다.
- 오버로딩 된 메서드들은 서로 다른 시그니처를 가지며, 컴파일러는 호출된 메서드와 일치하는 시그니처를 찾아 호출한다.
문제
👉 메서드 시그니처가 동일한 오버로딩 메서드를 정의하려고 할 때 발생하는 문제였다.
자바에서는 제네릭 타입 정보는 컴파일 시간에만 사용되며, 런타임에는 소거가 된다.
이것은 컴파일러가 제네릭 타입 Object 타입으로 대체하고, 이에 따라 메서드 시그니처가 동일하게 보이게 되어 발생하는 에러였다.
해결
👉 위 문제를 해결하기 위해 간단하게 메서드 이름 변경, 다른 매개변수 추가, 반환 자료형 변경 방법이 있다.
나는 오버로딩한 2 개의 메서드를 제네릭 타입을 적용하여 하나의 메서드로 구현했다.
public static <T> BoardInfo toBoardInfo(Page<T> page, List<Status> statusList) {
List<BoardItem> boardItems;
List<Board> boards;
if (page instanceof Page<Board>) {
boards = ((Page<Board>) page).getContent();
} else if (page instanceof Page<Like>) {
boards = ((Page<Like>) page).stream()
.map(Like::getBoard)
.toList();
} else {
throw new IllegalArgumentException("Unsupported page type");
}
boardItems = IntStream.range(0, boards.size())
.mapToObj(i -> toBoardItem(boards.get(i), statusList.get(i)))
.toList();
return BoardInfo.builder()
.boardItems(boardItems)
.listSize(boardItems.size())
.totalPage(page.getTotalPages())
.totalElements(page.getTotalElements())
.isFirst(page.isFirst())
.isLast(page.isLast())
.build();
}
<T> 타입으로는 Board or Like 엔티티가 오게 됩니다.
if (n instanceof m) 을 통해 어떤 인스턴스인지 확인을 하여 타입에 따라 로직을 다르게 반영할 수 있었습니다.
메서드(함수)에 제네릭 타입을 적용하기 위해서는 “<T> BoardInfo”처럼 자료형 앞에 작성과 매개변수에 Page <T>처럼 작성해 주어야 합니다.
반응형