이 코드의 출력 결과는:
Animal Dog
입니다.
각 if문이 왜 true인지 자세히 설명해볼게요.
class Animal {}
class Dog extends Animal {}
Animal 클래스가 있고, Dog 클래스는 Animal을 상속합니다.Dog는 Animal의 자식 클래스입니다.public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a는 Animal 타입의 참조 변수이지만, 실제 Dog 인스턴스를 참조합니다.타입: Animal
실제 객체: Dog
┌─────────────┐
a ---> │ Dog 객체 │
└─────────────┘
if (a instanceof Animal)a는 Animal 타입으로 선언되었고, Dog는 Animal의 하위 클래스이므로a가 가리키는 객체는 Animal 타입으로 간주될 수 있음 → true출력: Animal
if (a instanceof Dog)a가 실제로 참조하는 객체는 Dog 인스턴스입니다.instanceof Dog도 true출력: Dog
System.out.print("Animal ");
System.out.print("Dog ");
결과:
Animal Dog
| 조건 | 결과 | 이유 |
|---|---|---|
a instanceof Animal | true | Dog은 Animal의 자식 → 부모 타입도 포함됨 |
a instanceof Dog | true | 실제로 Dog 객체를 참조 중 |
좋아, 너가 궁금해하는 instanceof는 Java에서 매우 중요한 연산자야.
초보자가 자주 보지만 정확히 왜 쓰이는지, 어떻게 작동하는지 헷갈릴 수 있어.
아래에서 완전히 해부해서 설명해줄게.
instanceof 연산자의 정체instanceof는 객체가 특정 클래스(또는 그 자식)인지 확인할 때 사용하는 논리 연산자야.
결과는 true 또는 false (boolean 값)으로 나와.
객체참조변수 instanceof 클래스명
| 역할 | 상세 설명 |
|---|---|
| 1. 객체의 실제 타입 확인 | 런타임 시점에 객체가 특정 클래스(또는 그 하위 클래스)인지 확인 |
| 2. 안전한 다운캐스팅 전 검사 | 강제 형변환((Dog) a) 전에 그 객체가 진짜 Dog인지 확인 |
| 3. 타입에 따라 다른 처리 | 조건문으로 객체의 타입에 따라 서로 다른 로직을 처리할 수 있게 해줌 |
class Animal {}
class Dog extends Animal {}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
System.out.println(a instanceof Animal); // true
System.out.println(a instanceof Dog); // true
}
}
Animal a = new Dog();
메모리 구조:
┌───────────────┐
a →│ Dog 객체 │
└───────────────┘
a instanceof Animal → true (Dog는 Animal의 자식이므로 포함됨)
a instanceof Dog → true (실제로 Dog 객체니까 당연히 true)
null은 항상 falseAnimal a = null;
System.out.println(a instanceof Animal); // false
→ 이유: null은 어떤 객체도 가리키지 않기 때문에, 타입과 무관하게 무조건 false
ClassCastException→ 그래서 instanceof로 먼저 확인하고 형변환해야 해
Animal a = new Animal();
Dog d = (Dog) a; // 런타임 오류! Animal은 Dog가 아님!
해결 방법:
if (a instanceof Dog) {
Dog d = (Dog) a; // 안전하게 캐스팅
}
instanceof는 상속 관계 또는 인터페이스 구현 관계가 있어야 검사 가능해.
예:
interface Pet {}
class Cat implements Pet {}
Pet p = new Cat();
System.out.println(p instanceof Cat); // true
void handle(Animal a) {
if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark();
} else if (a instanceof Cat) {
Cat c = (Cat) a;
c.meow();
}
}
이런 구조는 **다형성(polymorphism)**과 instanceof를 함께 써서
유연하게 동작을 바꾸는 대표 예야.
| 항목 | 설명 |
|---|---|
| 역할 | 객체가 특정 타입인지 확인 (true/false) |
| 언제 사용? | 다운캐스팅 전에 안전성 검사할 때, 타입에 따라 분기할 때 |
| 특징 | 런타임 시점 검사, 상속·인터페이스만 가능, null은 항상 false |
| 주의점 | instanceof 없이 형변환하면 위험, 반드시 체크하고 캐스팅할 것 |