타입 안정성은 무엇이며 왜 중요할까요? #7
Replies: 4 comments
-
타입 안정성의 의미저는 타입 안정성을 잘못된 타입의 값이 프로그램 안으로 들어오는 것을 가능한 한 컴파일 시점에 막아주는 성질이라고 이해했습니다. 즉, 타입 안정성이 높다는 것은 단순히 코드가 깔끔하다는 의미보다, 초기 문제예를 들어 제네릭이 없던 시절의 컬렉션은 Object 기반으로 값을 다뤘습니다. List numbers = new ArrayList();
numbers.add(1);
numbers.add("문자열");
Integer number = (Integer) numbers.get(1);위 코드는 컴파일은 될 수 있지만, 실제 실행 시점에 ClassCastException이 발생합니다. 문제는 잘못된 값이 들어간 시점과 문제가 터지는 시점이 다르다는 점입니다. 이런 코드는 규모가 커질수록 원인을 찾기 어려워지고, 제네릭으로 해결제네릭은 이 문제를 타입 파라미터로 해결합니다. List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add("문자열"); // 컴파일 에러이제 List는 Integer만 담을 수 있는 컬렉션이라는 의도가 타입에 드러납니다. 덕분에 잘못된 타입의 값은 런타임이 아니라 컴파일 시점에 차단됩니다. 즉, 제네릭은 Object와 형변환에 의존하던 코드를 '타입 시스템' 안으로 끌어들여서, EnumEnum도 비슷한 맥락이라고 생각합니다. Enum이 없으면 특정 상태나 종류를 문자열 또는 정수 상수로 표현하는 경우가 많습니다. static final String MONDAY = "MONDAY";
static final String TUESDAY = "TUESDAY";
void reserve(String day) {
// ...
}이 방식의 문제는 아무 문자열이나 들어올 수 있다는 점입니다.
즉, 메서드는 요일을 기대하지만 타입은 단순히 String이기 때문에, Enum을 사용하면 허용 가능한 값의 범위를 타입으로 제한할 수 있습니다. enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
void reserve(Day day) {
// ...
}
----
reserve(Day.MONDAY);
reserve("MONDY"); // 컴파일 에러이제 reserve()에는 Day 타입의 값만 전달할 수 있습니다. 즉, Enum은 “아무 문자열”이 아니라 정해진 후보 중 하나만 사용할 수 있는 타입을 만들어줍니다. 결국 제네릭과 Enum은 둘 다 개발자의 의도를 타입으로 표현한다는 공통점이 있다고 생각합니다. List → 이 컬렉션에는 Integer만 들어간다. 이처럼 타입으로 의도를 표현하면, 컴파일러가 그 의도를 함께 검증해줄 수 있습니다. 타입 안정성 보장 안할 경우의 문제들타입 안정성을 보장하지 않으면 대표적으로 이런 문제가 생긴다고 생각합니다. 1. 런타임 예외 가능성이 커진다잘못된 타입의 값이 컴파일 시점에 걸러지지 않기 때문에, 2. 잘못된 값이 들어와도 바로 알아차리기 어렵다문제가 발생한 지점과 원인이 된 지점이 멀어질 수 있습니다. 3. 코드의 의도가 타입에 드러나지 않는다String status만 보면 어떤 값이 들어와야 하는지 알기 어렵습니다. 최종 정리그래서 저는 타입 안정성을 이렇게 정리할 수 있을 것 같습니다. 타입 안정성은 잘못된 값이 들어올 가능성을 타입 시스템을 통해 줄이고, 제네릭은 컬렉션이나 클래스 내부에서 다룰 값의 타입을 명확히 제한해 타입 안정성을 높였고, |
Beta Was this translation helpful? Give feedback.
-
|
모카가 자세히 설명해주셨네요! 자바는 Enum과 제네릭을 도입해서 타입 안정성을 어떻게 높일 수 있었나요?
두 기능 모두 의도한 형태의 데이터만 허용한다는 특징이 있습니다. 그렇게되면 의도하지 않은 값들을 방어해 해당 자료형의 변수를 믿고 사용할 수 있다는 장점이 있는 것 같아요. (추가) 자바에서 타입안정성을 높이는 다른 방법추가로 자바에서 타입안정성을 높이는 방법에 대해 찾아보았을 때 VO를 사용하는 방법도 있다고 하네요! 원시 타입이나 String을 그대로 쓰면 의미가 같은 타입끼리 섞일 위험이 있지만 VO로 분리하면 이를 컴파일 단계에서 방지할 수 있습니다. 예를 들어 위와 같이 다른 클래스로 해당 값을 감싸게되면, 인자 순서를 바꾸었을 때 컴파일되지 않기에 타입 안정성을 보장할 수 있다고합니다! 추가 학습 키워드: Primitive Obsession 안티패턴 |
Beta Was this translation helpful? Give feedback.
-
타입 안정성은 무엇이며, 보장하지 않은 경우 어떤 문제가 발생할 수 있을까?
자바는 Enum과 제네릭을 도입하여, 타입 안정성을 어떻게 높일 수 있을까?
제네릭을 사용하면, 런타임시 발생할 수 있는 문제를 컴파일 시점으로 당겨 타입 안정성을 높입니다. 위 모카의 예시가 적절하겠네요. 또한 제네릭을 사용하면 타입을 보존합니다. Enum은 가능한 값을 미리 제한하여 타입 안정성을 높입니다. TMITMI 제네릭은 타입 안정성을 유지하며, 확장에 열려있도록 도와줍니다.
간단한 예시로, new ThemeRepository();
new ReservationRepository();그러나 여기에 제네릭을 적용하면, 추가 클래스 작성 없이, 확장성있는 코드를 적용할 수 있습니다. public class Repository<T> {
private final List<T> data = new ArrayList<>();
public void save(T value) {
data.add(value);
}
public T find() {
return data.getFirst();
}
}
// 사용 예시
Repository<Theme> themeRepository = new Repository<>();
Repository<Reservation> reservationRepository = new Repository<>(); |
Beta Was this translation helpful? Give feedback.
-
타입 안정성은 무엇이며, 보장하지 않은 경우 어떤 문제가 발생할 수 있을까?타입 안정성은 넓은 의미에서 예상한 타입의 값만 다루도록 보장하는 것을 의미합니다. 예를 들어, String으로 정의된 변수에 int형 데이터가 들어오면 컴파일 단계에서 막히는 것 또한 타입 안정성이 보장된다고 말할 수 있습니다. 그렇다면 컬렉션의 경우는 어떨까요? 제네릭이 도입되기 이전에는 List의 원소의 타입을 코드 단계에서 정의하지 않고 사용할 수 있었습니다. (단순 Raw Type으로 사용) List a = new List();만약에 해당 리스트 a가 String을 담는 컬렉션이었는데, a.add(1)을 한다면 논리적 오류가 발생합니다. 여기서 문제는 이 오류의 발생을 컴파일 단계가 아닌 런타임 단계에서 발견할 수 있다는 점입니다. 따라서 타입 안정성이 중요한 이유는 런타임 단계에서 발생할 위험성을 컴파일단계에서 미리 체크하고 안정성을 높기 위함 입니다. 결국, 논리적인 연산 혹은 비교에서 각 피연산자들은 같은 종류여야 논리적으로 말이 됩니다. 이를 타입으로 강제하여 컴파일 단계에서 확인하자는 매커니즘입니다. 자바는 Enum과 제네릭을 도입하여, 타입 안정성을 어떻게 높일 수 있을까?
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
자바의 제네릭이나 Enum 클래스가 생겨난 각각의 배경 속에는 공통적으로 타입 안정성을 높이기 위한 목적도 포함되어 있습니다.
Beta Was this translation helpful? Give feedback.
All reactions