객체가 특정 클래스 또는 인터페이스의 인스턴스인지 여부를 런타임에 확인하는 데 사용되는 이항 연산자이다.
class Animal {
public void speak() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@Override
public void speak() {
System.out.println("멍멍!");
}
public void bark() {
System.out.println("나는 개라서 짖을 수 있습니다.");
}
}
class Cat extends Animal {
@Override
public void speak() {
System.out.println("야옹!");
}
public void scratch() {
System.out.println("나는 고양이라서 할퀼 수 있습니다.");
}
}
public class InstanceOfExample {
public static void main(String[] args) {
Animal myAnimal1 = new Dog();
Animal myAnimal2 = new Cat();
Animal myAnimal3 = new Animal(); // Animal 자체의 인스턴스
String someString = "Hello"; // 다른 타입의 객체
System.out.println("myAnimal1이 Dog의 인스턴스인가? " + (myAnimal1 instanceof Dog));
System.out.println("myAnimal1이 Cat의 인스턴스인가? " + (myAnimal1 instanceof Cat));
System.out.println("myAnimal1이 Animal의 인스턴스인가? " + (myAnimal1 instanceof Animal));
System.out.println("myAnimal1이 Object의 인스턴스인가? " + (myAnimal1 instanceof Object)); // 모든 객체는 Object의 인스턴스
System.out.println("\nmyAnimal2이 Dog의 인스턴스인가? " + (myAnimal2 instanceof Dog));
System.out.println("myAnimal2이 Cat의 인스턴스인가? " + (myAnimal2 instanceof Cat));
System.out.println("\nmyAnimal3이 Dog의 인스턴스인가? " + (myAnimal3 instanceof Dog));
System.out.println("myAnimal3이 Animal의 인스턴스인가? " + (myAnimal3 instanceof Animal));
// null 객체에 대한 instanceof 검사
Animal nullAnimal = null;
System.out.println("\nnullAnimal이 Animal의 인스턴스인가? " + (nullAnimal instanceof Animal)); // false 반환
// 다른 타입의 객체에 대한 instanceof 검사 (컴파일 오류 없음)
System.out.println("someString이 String의 인스턴스인가? " + (someString instanceof String));
System.out.println("someString이 Animal의 인스턴스인가? " + (someString instanceof Animal)); // false 반환
System.out.println("\n--- instanceof를 활용한 타입 캐스팅 ---");
// myAnimal1이 Dog의 인스턴스인지 확인 후, Dog 타입으로 안전하게 다운캐스팅
if (myAnimal1 instanceof Dog) {
Dog dog = (Dog) myAnimal1; // 안전한 다운캐스팅
dog.bark(); // Dog 클래스에만 있는 메서드 호출 가능
}
if (myAnimal2 instanceof Cat) {
Cat cat = (Cat) myAnimal2;
cat.scratch(); // Cat 클래스에만 있는 메서드 호출 가능
}
}
}
조건문에 주로 사용되어 인터페이스의 인스턴스인지를 확인할 떄 주로 사용된다.
자바 14부터 instanceOf 한 줄로 캐스팅이 가능하다.
if (myAnimal1 instanceof Dog dog) { // 검사와 동시에 새로운 변수 'dog'에 캐스팅된 값 할당
dog.bark(); // 'dog' 변수를 바로 사용 가능
}
조건문 안에 있어도 캐스팅이 되는 것이다.
변수나 표현식의 데이터 타입을 다른 데이터 타입으로 변환하는 과정이다.
기본 변환: int를 String으로, String을 int로. 그러니까 이런 거다. (int) 123.456 괄호 안에 타입 값이 써져 있으면 축소 변환이다. 큰 타입에서 작은 타입으로 바꿀 때 사용된다. 작은 타입에서 큰 타입은 데이터 손실이 없으므로 자연스레 바꾸면 된다.
참조 타입 캐스팅: 클래스나 인터페이스 사이에서 객체의 참조 타입을 바꾸는 것이다. 여기서도 종류는 두 가지다.