Home > Archive > Java_archive > ☕️[Java] instanceof

☕️[Java] instanceof
Java Programming Language

instanceof

다형성에서 참조형 변수는 이름 그대로 다양한 지식을 대상으로 참조할 수 있습니다.
그런데 참조하는 대상이 다양하기 때문에 어떤 인스턴스를 참조하고 있는지 확인하려면 어떻게 해야할까요?

Parent parent1 = new Parent();
Parent parent2 = new Child()
  • 여기서 Parent는 자신과 같은 Parent의 인스턴스도 참조할 수 있고, 자식 타입인 Child의 인스턴스도 참조할 수 있습니다.
    • 이때 parent1, parent2 변수가 참조하는 인스턴스의 타입을 확인하고 싶다면 instanceof 키워드를 사용하면 됩니다.

예제를 봅시다.

package poly.basic;

public class CastingMain5 {

  public static void main(String[] args) {
    Parent parent1 = new Parent();
    System.out.println("parent1 호출");
    call(parent1);

    Parent parent2 = new Child();
    System.out.println("parent2 호출");
    call(parent2);
  }

  private static void call(Parent parent) {
    parent.parentMethod();

    if (parent instanceof Child) {
      System.out.println("Child 인스턴스 맞음");
      Child child = (Child) parent;
      child.childMethod();
    }
  }
}

실행 결과

parent1 호출
Parent.parentMethod
parent2 호출
Parent.parentMethod
Child 인스턴스 맞음
Child.childMethod

call(Parent parent) 메서드를 봐봅시다.

  • 이 메서드는 매개변수로 넘어온 parent가 참조하는 타입에 따라서 다른 명령을 수행합니다.
    • 참고로 지금처럼 다운캐스팅을 수행하기 전에는 먼저 instanceof를 사용해서 원하는 타입으로 변경이 가능한지 확인한 다음에 다운캐스팅을 수행하는 것이 안전합니다.

해당 메서드를 처음 호출할 때 parentParent의 인스턴스를 참조합니다.

parent instanceof Child // parent는 Parent의 인스턴스
new Parent() instanceof Child // false
  • parentParent의 인스턴스를 참조하므로 false를 반환합니다.

해당 메서드를 다음으로 호출할 때 parentChild의 인스턴스를 참조합니다.

parent instanceof Child // parent는 Child의 인스턴스
new Child() instanceof Child // true

참고로 instanceof 키워드는 오른쪽 대상의 자식 타입을 왼쪽에서 참조하는 경우에도 true를 반환합니다.

parent instanceof Parent // parent는 Child의 인스턴스

new Parent() instanceof Parent // parent가 Parent의 인스턴스를 참조하는 경우: true
new Child() instanceof Parent // parent가 Child의 인스턴스를 참조하는 경우: true
  • 쉽게 이야기해서 오른쪽에 있는 타입에 왼쪽에 있는 인스턴스의 타입이 들어갈 수 있는지 대입해보면 됩니다.
    • 대입이 가능하면 true, 불가능하면 false가 됩니다.
new Parent() instanceof Parent
Parent p = new Parent() // 같은 타입 true

new Child() instancof Parent
Parent p = new Child() // 부모는 자식을 담을 수 있다. true

new Parent() instanceof Child
Child c = new Parent() // 자식은 부모를 담을 수 없다. false

new Child() instanceof Child
Child c = new Child() // 같은 타입 true

자바 16 - Pattern Matching for instanceof

자바 16부터는 instanceof를 사용하면서 동시에 변수를 선언할 수 있습니다.

다음 코드를 참고합시다.

package poly.basic;

public class CastingMain6 {

  public static void main(String[] args) {
    Parent parent1 = new Parent();
    System.out.println("parent1 호출");
    call(parent1);

    Parent parent2 = new Child();
    System.out.println("parent2 호출");
    call(parent2);
  }

  private static void call(Parent parent) {
    parent.parentMethod();
    // Child 인스턴스인 경우 childMethod() 실행
    if (parent instanceof Child child) {
      System.out.println("Child 인스턴스 맞음");
      child.childMethod();
    }
  }
}

실행 결과

parent1 호출
Parent.parentMethod
parent2 호출
Parent.parentMethod
Child 인스턴스 맞음
Child.childMethod
  • 덕분에 인스턴스가 맞는 경우 직접 다운캐스팅 하는 코드를 생략할 수 있습니다.