instanceof 연산자
instanceof 연산자는 객체가 특정 클래스, 서브클래스, 또는 특정 인터페이스를 구현한 클래스의 인스턴스인지 확인하는 데 사용됩니다. 이는 객체 지향 프로그래밍에서 객체의 타입을 런타임에 확인할 때 매우 유용합니다.
사용 형식:
public class InstanceofExample {
public static void main(String[] args) {
Animal animal = new Dog();
Dog dog = new Dog();
Cat cat = new Cat();
System.out.println("animal instanceof Animal: " + (animal instanceof Animal));
System.out.println("animal instanceof Dog: " + (animal instanceof Dog));
System.out.println("animal instanceof Cat: " + (animal instanceof Cat));
System.out.println("dog instanceof Animal: " + (dog instanceof Animal));
System.out.println("dog instanceof Dog: " + (dog instanceof Dog));
System.out.println("dog instanceof Cat: " + (dog instanceof Cat));
System.out.println("cat instanceof Animal: " + (cat instanceof Animal));
System.out.println("cat instanceof Dog: " + (cat instanceof Dog));
System.out.println("cat instanceof Cat: " + (cat instanceof Cat));
// instanceof와 타입 캐스팅
if (animal instanceof Dog) {
Dog specificDog = (Dog) animal;
specificDog.bark();
}
// instanceof와 인터페이스
if (animal instanceof Pet) {
((Pet) animal).play();
}
}
}
class Animal {}
class Dog extends Animal implements Pet {
void bark() {
System.out.println("Woof!");
}
}
class Cat extends Animal {}
interface Pet {
void play();
}
이 프로그램의 실행 결과는 다음과 같습니다:
animal instanceof Animal: true
animal instanceof Dog: true
animal instanceof Cat: false
dog instanceof Animal: true
dog instanceof Dog: true
dog instanceof Cat: false
cat instanceof Animal: true
cat instanceof Dog: false
cat instanceof Cat: true
Woof!
주의사항 및 특징
상속 관계:
- instanceof는 상속 관계를 고려합니다.
- 부모 클래스나 인터페이스도 true를 반환합니다.
null 처리:
- null 객체에 대해 instanceof를 사용하면 항상 false를 반환합니다.
인터페이스 확인:
- instanceof는 인터페이스 구현 여부도 확인할 수 있습니다.
타입 캐스팅:
- instanceof로 타입을 확인한 후 안전한 타입 캐스팅을 수행할 수 있습니다.
성능 고려:
- instanceof는 런타임에 타입을 확인하므로, 과도한 사용은 성능에 영향을 줄 수 있습니다.
사용 예시:
public class InstanceofFeatures {
public static void main(String[] args) {
// 상속 관계 확인
Animal animal = new Dog();
System.out.println("animal instanceof Animal: " + (animal instanceof Animal));
System.out.println("animal instanceof Dog: " + (animal instanceof Dog));
// null 처리
Object nullObject = null;
System.out.println("nullObject instanceof Object: " + (nullObject instanceof Object));
// 인터페이스 구현 확인
Dog dog = new Dog();
System.out.println("dog instanceof Pet: " + (dog instanceof Pet));
// 타입 캐스팅
Object obj = new Dog();
if (obj instanceof Dog) {
Dog specificDog = (Dog) obj;
specificDog.bark();
}
// 성능 고려
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
if (obj instanceof Dog) {}
}
long endTime = System.currentTimeMillis();
System.out.println("Time taken for 10 million instanceof checks: " + (endTime - startTime) + " ms");
// instanceof와 instanceof의 중첩 사용
if (obj instanceof Animal && obj instanceof Pet) {
System.out.println("Object is both Animal and Pet");
}
}
}
class Animal {}
class Dog extends Animal implements Pet {
void bark() {
System.out.println("Woof!");
}
}
interface Pet {}
출력 결과는 다음과 같습니다:
animal instanceof Animal: true
animal instanceof Dog: true
nullObject instanceof Object: false
dog instanceof Pet: true
Woof!
Time taken for 10 million instanceof checks: X ms (X는 실행 환경에 따라 다름)
Object is both Animal and Pet
instanceof와 타입 캐스팅
instanceof는 안전한 타입 캐스팅을 위해 자주 사용됩니다:
public class InstanceofCastingExample {
public static void main(String[] args) {
Object obj = new Dog();
// 안전한 타입 캐스팅
if (obj instanceof Dog) {
Dog dog = (Dog) obj;
dog.bark();
}
// 인터페이스 타입 캐스팅
if (obj instanceof Pet) {
Pet pet = (Pet) obj;
pet.play();
}
// 부모 클래스 타입 캐스팅
if (obj instanceof Animal) {
Animal animal = (Animal) animalSound(obj);
}
// 안전하지 않은 타입 캐스팅의 위험성
try {
Cat cat = (Cat) obj;
cat.meow();
} catch (ClassCastException e) {
System.out.println("ClassCastException occurred: " + e.getMessage());
}
}
private static Animal animalSound(Animal animal) {
if (animal instanceof Dog) {
((Dog) animal).bark();
} else if (animal instanceof Cat) {
((Cat) animal).meow();
}
return animal;
}
}
class Animal {}
class Dog extends Animal implements Pet {
void bark() {
System.out.println("Woof!");
}
}
class Cat extends Animal {
void meow() {
System.out.println("Meow!");
}
}
interface Pet {
void play();
}
출력 결과는 다음과 같습니다:
Woof!
Woof!
Woof!
ClassCastException occurred: java.lang.ClassCastException: Dog cannot be cast to Cat
instanceof와 인터페이스
instanceof는 인터페이스 구현 여부도 확인할 수 있습니다:
public class InstanceofInterfaceExample {
public static void main(String[] args) {
Animal animal = new Dog();
Object obj = new Cat();
// 인터페이스 구현 여부 확인
System.out.println("animal instanceof Pet: " + (animal instanceof Pet));
System.out.println("obj instanceof Pet: " + (obj instanceof Pet));
// 인터페이스와 클래스의 조합
if (animal instanceof Animal && animal instanceof Pet) {
System.out.println("Animal is both Animal and Pet");
}
// 메서드 매개변수 타입 확인
processAnimal(animal);
processAnimal(obj);
// 인터페이스 구현 여부에 따른 동작
if (animal instanceof Flyable) {
((Flyable) animal).fly();
} else {
System.out.println("This animal cannot fly");
}
}
private static void processAnimal(Object obj) {
if (obj instanceof Animal) {
Animal animal = (Animal) obj;
animal.makeSound();
} else {
System.out.println("Not an Animal");
}
}
}
class Animal {
void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal implements Pet, Flyable {
@Override
public void play() {
System.out.println("Dog is playing");
}
@Override
public void fly() {
System.out.println("Dog is flying");
}
}
class Cat extends Animal implements Pet {
@Override
public void play() {
System.out.println("Cat is playing");
}
}
interface Pet {
void play();
}
interface Flyable {
void fly();
}
출력 결과는 다음과 같습니다:
animal instanceof Pet: true
obj instanceof Pet: true
Animal is both Animal and Pet
Animal makes a sound
Not an Animal
This animal cannot fly
instanceof와 상속 계층
instanceof는 상속 계층을 따라 확인합니다:
public class InstanceofHierarchyExample {
public static void main(String[] args) {
Vehicle vehicle = new Car();
Object obj = new Truck();
// 상속 계층 확인
System.out.println("vehicle instanceof Car: " + (vehicle instanceof Car));
System.out.println("vehicle instanceof Vehicle: " + (vehicle instanceof Vehicle));
System.out.println("vehicle instanceof Object: " + (vehicle instanceof Object));
// Object 타입으로 선언된 객체의 실제 타입 확인
System.out.println("obj instanceof Truck: " + (obj instanceof Truck));
System.out.println("obj instanceof Vehicle: " + (obj instanceof Vehicle));
System.out.println("obj instanceof Object: " + (obj instanceof Object));
// 메서드 매개변수 타입 확인
processVehicle(vehicle);
processVehicle(obj);
// 상속 계층에 따른 동작 처리
if (vehicle instanceof Car) {
((Car) vehicle).drive();
} else if (vehicle instanceof Truck) {
((Truck) vehicle).haul();
} else {
System.out.println("Unknown vehicle type");
}
}
private static void processVehicle(Object obj) {
if (obj instanceof Vehicle) {
Vehicle vehicle = (Vehicle) obj;
vehicle.move();
} else {
System.out.println("Not a Vehicle");
}
}
}
class Vehicle {
void move() {
System.out.println("Vehicle is moving");
}
}
class Car extends Vehicle {
void drive() {
System.out.println("Car is driving");
}
}
class Truck extends Vehicle {
void haul() {
System.out.println("Truck is hauling");
}
}
vehicle instanceof Car: true
vehicle instanceof Vehicle: true
vehicle instanceof Object: true
obj instanceof Truck: true
obj instanceof Vehicle: true
obj instanceof Object: true
Vehicle is moving
Vehicle is moving
Car is driving
instanceof 연산자는 Java의 다형성과 객체 지향 프로그래밍의 유연성을 활용할 때 매우 유용합니다. 특히 런타임에 객체의 타입을 확인하고 적절한 처리를 해야 할 때 중요한 역할을 합니다.
편히 모아진 글 보시려면 아래 위키독스 링크 >>
https://wikidocs.net/book/17111
'JAVA' 카테고리의 다른 글
JAVA 표현식 [코딩백과 with JAVA] (1) | 2024.12.21 |
---|---|
JAVA 비트 연산자, 시프트 연산자 [코딩백과 with JAVA] (0) | 2024.12.21 |
JAVA 조건 연산자 [코딩백과 with JAVA] (0) | 2024.12.21 |
JAVA 비교 연산자 [코딩백과 with JAVA] (0) | 2024.12.21 |
JAVA 단항 연산자 [코딩백과 with JAVA] (0) | 2024.12.21 |