일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Til
- join
- 정처기
- Kotlin
- 정보처리기사
- 프로그래머스
- 알고리즘
- doitandroid
- MySQL
- select
- CS
- 자료구조
- 인프런
- groupby
- 혼공파
- 혼공챌린지
- 기술면접
- 티스토리챌린지
- 자바
- 안드로이드스튜디오
- 카카오코테
- 코테
- 스터디
- java
- SQL
- 안드로이드
- 오블완
- Android
- 코틀린
- 혼공단
- Today
- Total
Welcome! Everything is fine.
[TIL] 계산기 과제 해설, 와일드카드, 타입 이레이저 본문
✅ 계산기 과제 해설
과제 제출 마감 직후, 바로 튜터님의 해설 세션이 시작되었다. 해설을 들으며 내가 빼먹은 부분이나 몰랐던 부분을 알게 되었다.
✔️ null을 조심하자
보통 문자열이 같은지 확인하기 위해 equals() 메서드를 쓸 때, 다음과 같이 사용해왔다.
input.equals("exit");
하지만 확실히 null이 될 수 없는 것을 앞에 두는 것이 좋다고 한다.
“exit”.equals(input);
✔️ 요구사항은 꼼꼼히
예외처리를 할 때, 여러 상황에서 살펴봤지만 정작 양의 정수로 제한하는 예외 처리를 빼먹었다.
요구사항을 더 꼼꼼히 살피는 습관을 들이자.
if (num1 < 0) {
throw new IllegalStateException("양의 정수만 입력할 수 있습니다.");
}
✔️ 타입 매개변수 제한이 중요!
Lv.3에서 사용된 제네릭은 사용해봤다는 것이 중요하다고 하셨다. 특히 <T extends Number> 와 같이 타입 매개변수 제한을 통해 숫자만 받도록 하는 것이 중요하다.
튜터님께서 올려주신 코드를 뜯어보며 부족한 부분을 더 채워봐야할 것 같다.
✅ 자바 강의 듣기
와일드카드
와일드카드란 제네릭을 쉽게 쓸 수 있도록 도와주는 도구로, 타입 인자가 정해진 제네릭 타입을 전달 받아서 활용할 때 사용한다. 다음과 같이 <> 안에 ?를 넣어 사용한다.
static void printWildcardV1(Box<?> box) {
System.out.println("? = " + box.get());
}
- ?의 뜻은 모든 타입을 다 받을 수 있다는 뜻이다.
- 매개변수로 제네릭 타입을 받을 수 있는 일반적인 메서드이다.
- 더 단순하기 때문에 사용이 권장된다.
와일드카드에도 다음과 같이 extends 키워드를 이용해 상한 제한을 둘 수 있다. Box<? extends Animal>과 같이 쓴다면, Animal과 그 하위 타입만 입력받을 수 있다.
static void printWildcardV2(Box<? extends Animal> box) {
Animal animal = box.get();
System.out.println("이름 = " + animal.getName());
}
또한 와일드카드는 super 키워드를 이용해 하한도 지정할 수 있다. Box<? super Animal> 과 같이 쓴다면, Animal과 그 상위 타입만 입력받을 수 있다. 즉, 아래 예시에서는 Animal과 Object 타입만 허용된다.
static void writeBox(Box<? super Animal> box) {
box.set(new Dog("망망이", 100));
}
타입 이레이저
타입 이레이저란 자바 컴파일 단계에서만 제네릭이 사용되고, 컴파일 이후에는 제네릭 정보가 삭제되는 것을 말한다.
예를 들어 다음과 같이 제네릭 타입을 선언한 후에 Integer 타입 인자를 전달했다면,
public class Box<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
자바 컴파일러는 컴파일 시점에 다음과 같이 이해한다.
public class Box<Integer> {
private Integer value;
public void set(Integer value) {
this.value = value;
}
public Integer get() {
return value;
}
}
그리고나서 컴파일이 끝나면 제네릭 관련 정보를 모두 삭제해서 .class 파일에는 다음과 같은 정보가 생성된다.
public class Box {
private Object value;
public void set(Object value) {
this.value = value;
}
public Object get() {
return value;
}
}
값을 꺼낼 때도 자바 컴파일러가 Integer로 캐스팅하는 코드를 추가해주기 때문에 문제가 발생하지 않는다.
void main() {
GenericBox box = new GenericBox();
box.set(10);
Integer result = (Integer) box.get(); // 컴파일러가 캐스팅 추가
}
하지만, 이런 타입 이레이저 방식으로 인해 다음과 같은 코드를 작성할 수 없다. 여기서 T는 모두 런타임에 Object로 바뀌기 때문에, instanceof는 항상 Object와 비교하게 되어서 소용이 없어진다. new T() 또한 항상 new Object가 된다.
class EraserBox<T> {
public boolean instanceCheck(Object param) {
return param instanceof T; // 오류
}
public void create() {
return new T(); // 오류
}
}
'TIL' 카테고리의 다른 글
[TIL] 네트워크, HTTP와 HTTP의 특징 (0) | 2025.01.22 |
---|---|
[TIL] enum 클래스에 연산자 담기, BiFunction 인터페이스 (0) | 2025.01.08 |
[TIL] 접근제어자 ~ 추상클래스, 계산기 과제 완료 (1) | 2025.01.07 |
[TIL] 로그인 페이지에서 메인 페이지 이동 시 경로 문제 (0) | 2024.12.26 |
[TIL] Firebase로 간단한 로그인/회원가입 구현 (0) | 2024.12.24 |