Java instanceof와 안전한 형변환

코딩Java
읽는데 8분 소요
처음 쓰여진 날: 2026-04-24
마지막 수정일: 2026-04-24
조회수:

요약

Java instanceof 연산자와 다운캐스팅을 알아봅니다. 업캐스팅된 참조를 실제 객체 타입으로 안전하게 되돌리는 방법, ClassCastException을 피하는 패턴을 정보처리기사 실기 대비 관점에서 정리합니다.

instanceof 핵심 정리

개념설명예시
instanceof참조가 특정 타입(하위 포함)의 객체를 가리키는지 확인a instanceof B
다운캐스팅부모 참조를 자식 타입으로 되돌리는 변환B b = (B) a;
업캐스팅자식 참조를 부모 타입으로 담는 변환 (자동)A a = new B();
ClassCastException잘못된 다운캐스팅 시 런타임에 발생하는 예외(B) 로 변환했는데 실제 객체가 B가 아님

왜 instanceof가 필요한가? 쌩기초

먼저 상속을 떠올려 보세요. DogAnimal을 상속받으면 "Dog은 Animal의 한 종류" 라는 관계가 생깁니다. 강아지도 결국 동물이듯, Java도 "Dog 객체는 Animal로 봐도 된다"고 봐줍니다. 그래서 Animal 타입의 변수에 Dog으로 만든 객체를 그대로 담을 수 있습니다.

java
코드 하이라이팅 중...

이렇게 자식 객체를 부모 타입 변수에 담는 것을 업캐스팅(upcasting) 이라고 부릅니다. 강아지를 "동물"이라는 더 큰 분류로 부르는 것과 같은 일이라, 일부러 변환 표시를 적지 않아도 Java가 자동으로 처리해 줍니다.

부모 타입으로 담으면 자식 기능이 안 보입니다

문제는, a가 가리키는 실제 객체는 Dog이지만 변수 자체는 Animal 타입이라는 점입니다. Java는 컴파일 시점에 변수에 적힌 타입(Animal)만 보고 "이 변수가 호출할 수 있는 메서드가 무엇인지" 검사합니다. Animalbark()가 없으므로, 실제 객체가 강아지여도 짖게 만들 수 없습니다.

java
코드 하이라이팅 중...

쉽게 비유하면, 강아지를 "동물 보관함"에 넣어둔 상황입니다. 안에는 분명히 강아지가 들어 있지만, 보관함 라벨이 "동물"이라서 "동물이 할 수 있는 일"만 시킬 수 있습니다.

업캐스팅 비유: Animal 라벨 박스에 담긴 Dog 객체. eat()만 보이고 bark()는 가려짐
업캐스팅하면 변수 라벨이 부모 타입(Animal)이라 자식 고유 기능(bark())이 가려집니다

강아지 전용 기능(bark())을 쓰려면 라벨을 다시 "강아지"로 바꿔줘야 합니다. 이렇게 부모 타입 라벨을 다시 자식 타입 라벨로 돌려놓는 것을 다운캐스팅(downcasting) 이라고 합니다.

java
코드 하이라이팅 중...

a변수 타입은 Animal 이지만 실제 객체는 Dog 이었습니다. (Dog) a는 "이 참조를 Dog 타입으로 봐줘"라는 표시이고, 그 결과를 새로운 변수 d에 담는 순간 d의 라벨은 Dog이 됩니다. 업캐스팅과 달리 다운캐스팅은 Java가 자동으로 해주지 않으므로 개발자가 (Dog)를 직접 적어야 합니다.

다운캐스팅으로 Animal a 라벨에서 Dog d 라벨로 같은 객체를 옮긴 그림
라벨만 Dog으로 바뀌었을 뿐 실제 객체는 그대로입니다. 이제 d.bark()를 호출할 수 있습니다

문제: 모든 다운캐스팅이 안전하지 않다

다운캐스팅은 컴파일러가 "개발자가 실제 타입을 안다"고 믿고 통과시키지만, 런타임에 실제 객체가 해당 타입이 아니면 ClassCastException이 발생합니다.

java
코드 하이라이팅 중...

이 런타임 실패를 막기 위해 변환 전에 실제 타입을 확인하는 것이 instanceof 연산자의 역할입니다.


instanceof 연산자 기초

x instanceof Tx가 가리키는 실제 객체가 T 타입이거나 T의 하위 타입이면 true, 아니면 false를 돌려줍니다.

java
코드 하이라이팅 중...

동작 기준: 실제 객체의 런타임 타입

instanceof선언 타입이 아닌 실제 객체의 타입을 본다는 점이 핵심입니다. 오버라이딩된 인스턴스 메서드가 실제 객체 기준으로 호출되는 것과 같은 원리입니다.

참조 선언실제 객체ref instanceof Dogref instanceof Animal
Animal a = new Dog();Dogtruetrue
Animal a = new Cat();Catfalsetrue
Animal a = null;없음falsefalse

선언 타입은 모두 Animal로 똑같지만, 실제 객체가 무엇인지에 따라 instanceof의 결과가 달라지는 것을 메모리 그림으로 확인해 보세요.

Animal a가 Dog/Cat/null을 가리킬 때 instanceof 검사 결과를 각각 보여주는 메모리 다이어그램
instanceof는 변수 라벨이 아닌 실제 객체(Dog/Cat) 기준으로 판단합니다. null이면 항상 false

안전한 다운캐스팅 패턴 기초

instanceof와 다운캐스팅을 결합하면 런타임 예외 없이 자식 타입의 기능을 호출할 수 있습니다.

java
코드 하이라이팅 중...

단계별 풀이 방법

  1. a instanceof Dogtrue이면 실제 객체는 Dog (또는 Dog의 하위 타입)
  2. 그 순간에만 (Dog) a로 다운캐스팅이 안전함이 보장됨
  3. 이후 d.bark()처럼 자식 고유 메서드를 자유롭게 호출

이 패턴은 "체크 → 변환 → 사용" 세 단계로 외워두면 편리합니다.

단계코드역할
체크if (a instanceof Dog)실제 타입이 맞는지 런타임 확인
변환Dog d = (Dog) a;참조 타입을 자식으로 되돌림
사용d.bark();자식 고유 기능 호출
안전한 다운캐스팅의 체크-변환-사용 3단계 흐름 다이어그램
체크가 통과한 순간에만 변환과 사용이 안전합니다. 체크를 건너뛰면 ClassCastException 위험

업캐스팅 vs 다운캐스팅 기초

구분업캐스팅다운캐스팅
방향자식 → 부모부모 → 자식
구문자동 (암시적)(자식타입) 명시 필요
안전성항상 안전실제 객체가 해당 자식이 아니면 실패
예시Animal a = new Dog();Dog d = (Dog) a;
확인 필요불필요instanceof로 확인 권장

업캐스팅이 항상 안전한 이유는 자식은 부모의 모든 기능을 가지고 있기 때문입니다. 반대로 다운캐스팅은 부모 참조가 실제로 어떤 자식인지 모르는 상태에서 "이건 Dog이야"라고 단정하는 것이므로 검증이 필요합니다.


자주 하는 실수 심화

실수올바른 이해
a instanceof T의 결과가 선언 타입에 따라 달라진다고 생각항상 실제 객체 기준입니다. 선언 타입은 관계 없습니다.
null도 예외로 잡아야 한다고 생각null instanceof T는 자동으로 false, 별도 검사 불필요
모든 형변환에 instanceof를 써야 한다고 생각업캐스팅은 자동이므로 불필요. 다운캐스팅에서만 사용
같은 계층이 아닌 타입으로 다운캐스팅 시도(Dog) new Cat()은 컴파일은 될 수 있어도 런타임에 ClassCastException

연습 문제

Java instanceof와 안전한 형변환 | 정처기 감자