인프런 커뮤니티 질문&답변

강리눅스님의 프로필 이미지
강리눅스

작성한 질문수

김영한의 실전 자바 - 중급 2편

정리

Shuttle에 많이 태우기 위해 코드를 수정한 후 생긴 사이드 이팩트

작성

·

29

0

 학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.


1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
```

package generic.test.ex3;

import generic.test.ex3.unit.BioUnit;

public class Shuttle<T extends BioUnit> {

    private BioUnit[] units;
    private int unitCount;

    public Shuttle() {
        units = new BioUnit[10];
    }

    public void in(T unit) {
        units[unitCount++] = unit;

    }

    public T out() {
        return (T) units[0];
    }

    public void showInfo() {
        for (int i = 0; i < unitCount; i++) {
            System.out.println("이름: " + units[i].getName() + " HP: " + units[i].getHp());
        }
    }

}

 

package generic.test.ex3;

import generic.test.ex3.unit.Marine;
import generic.test.ex3.unit.Zealot;
import generic.test.ex3.unit.Zergling;

public class ShuttleTest {
    public static void main(String[] args) {
        Shuttle<Marine> shuttle1 = new Shuttle<>();
        shuttle1.in(new Marine("마린", 40));
        shuttle1.in(new Marine("마린2", 45));
        shuttle1.showInfo();

        Shuttle<Zergling> shuttle2 = new Shuttle<>();
        shuttle2.in(new Zergling("저글링", 35));
        shuttle2.in(new Zergling("저글링2", 35));
        shuttle2.in(new Zergling("저글링3", 35));
        shuttle2.in(new Zergling("저글링4", 35));
        shuttle2.showInfo();

        Shuttle<Zealot> shuttle3 = new Shuttle<>();
        shuttle3.in(new Zealot("질럿", 100));
        shuttle3.in(new Zealot("질럿2", 100));
        shuttle3.in(new Zealot("질럿3", 100));
        shuttle3.in(new Zealot("질럿4", 100));
        shuttle3.showInfo();
        UnitPrinter.printV1(shuttle1);
        UnitPrinter.printV2(shuttle1);

    }
}

 

 

Shuttle을 생성하고 내부에 많이 태우고 싶어서 코드를 조금 수정해 보았습니다 !

 

그런데 코드를 이렇게 수정하니 문제풀이 시간 때

 

package generic.test.ex3;

import generic.test.ex3.unit.BioUnit;

public class UnitPrinter {

    public static <T extends BioUnit> void printV1(Shuttle<T> shuttle) {
        T out = shuttle.out();
        System.out.println("이름: " + out.getName() + "HP: " + out.getHp());
    }

    public static void printV2(Shuttle<? extends BioUnit> shuttle) {
        BioUnit out = shuttle.out();
        System.out.println("이름: " + out.getName() + "HP: " + out.getHp());
    }
}

이 코드를 출력하기 위해서 Shuttle 클래스에 out메서드에 unit 1명만 출력하기 위해 (T) units[0]을 반환하였는데요,

 

이렇게 한 덕분에 문제 요구사항 대로 잘 나왔지만,

Shuttle 클래스의 out 메서드에 이러한 린트가 발생합니다.

 

Unchecked cast: 'generic. test. ex3.unit. BioUnit' to 'T'

 

왜 이러한 문제가 발생하는지 파악을 하지 못했고,

혹시 코드를 이렇게 작성하게 된다면 어떤 문제점이 발생하는지, 어떻게 리팩터링 하면 좋을지 조언을 구하고 싶습니다 !

답변 1

1

안녕하세요. 강리눅스님, 공식 서포터즈 y2gcoder입니다.

제시해주신 메시지에서도 볼 수 있듯이 하위 클래스로 검사하지 않고 형변환이 일어나기 때문에 경고하는 메시지로 보입니다! 해당 코드에서는 문제가 발생할 것 같지는 않지만, 컴파일러 입장에서는 어쨋든 내부 배열의 타입이 BioUnit 인데 이를 BioUnit을 상속한 하위 클래스로 검사없이 형변환 하려고 하니 경고를 보여주는 것이라 생각해주시면 감사하겠습니다!

이는 본 강의를 끝까지 듣고 나시면 배울 컬렉션 프레임워크들 중 하나를 이용하실 수 있으실 겁니다! 컬렉션 프레임워크들은 제네릭을 지원하기 때문입니다 🙂

 

감사합니다.

강리눅스님의 프로필 이미지
강리눅스

작성한 질문수

질문하기