Java instanceof 연산자

1. 소개

이 빠른 자습서에서는 Java 의 instanceof 연산자에 대해 알아 봅니다 .

2. instanceof 연산자 는 무엇입니까 ?

instanceof는 객체가 주어진 유형인지 테스트하는 데 사용되는 이항 연산자입니다. 작업 결과는 true 또는 false 입니다. 인스턴스를 유형과 비교하기 때문에 유형 비교 연산자라고도합니다.

알 수없는 개체를 캐스팅하기 전에 항상 instanceof check를 사용해야합니다. 이렇게하면 런타임에 ClassCastException 을 방지하는 데 도움이됩니다 .

의 instanceof 연산자의 기본 구문은 다음과 같습니다

(object) instanceof (type)

instanceof 연산자 의 기본 예를 살펴 보겠습니다 . 먼저 Round 클래스를 만들어 보겠습니다 .

public class Round { // implementation details }

다음 으로 Round 를 확장 하는 Ring 클래스를 만들어 보겠습니다 .

public class Ring extends Round { // implementation details }

instanceof 를 사용 하여 Ring 의 인스턴스 가 Round 유형 인지 확인할 수 있습니다 .

@Test public void givenWhenInstanceIsCorrect_thenReturnTrue() { Ring ring = new Ring(); Assert.assertTrue(ring instanceof Round); }

3. instanceof 연산자 는 어떻게 작동합니까?

instanceof를 연산자는 IS-관계의 원리로 작동합니다 . is-a 관계의 개념은 클래스 상속 또는 인터페이스 구현을 기반으로합니다.

이를 증명하기 위해 Shape 인터페이스를 만들어 보겠습니다 .

public interface Shape { // implementation details }

Shape 인터페이스 를 구현 하고 Round 클래스를 확장하는 Circle 클래스도 만들어 보겠습니다 .

public class Circle extends Round implements Shape { // implementation details }

의 instanceof 결과가 될 것입니다 진정한 개체 유형의 인스턴스 인 경우 :

@Test public void givenWhenObjectIsInstanceOfType_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Circle); }

객체가 다음 유형의 하위 클래스 인스턴스 인 경우 에도 마찬가지입니다 .

@Test public void giveWhenInstanceIsOfSubtype_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Round); }

유형이 인터페이스 인 경우 객체가 인터페이스를 구현하면 true 를 반환 합니다 .

@Test public void givenWhenTypeIsInterface_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Shape); }

비교중인 객체와 비교중인 유형간에 관계가없는 경우 instanceof 연산자를 사용할 수 없습니다.

Shape 를 구현 하지만 Circle 과 관계가없는 새로운 Triangle 클래스를 만들어 보겠습니다 .

public class Triangle implements Shape { // implementation details }

이제 instanceof 를 사용 하여 CircleTriangle 의 인스턴스 인지 확인합니다 .

@Test public void givenWhenComparingClassInDiffHierarchy_thenCompilationError() { Circle circle = new Circle(); Assert.assertFalse(circle instanceof Triangle); }

Circle 클래스 와 Triangle 클래스 간에 관계가 없기 때문에 컴파일 오류가 발생합니다 .

java.lang.Error: Unresolved compilation problem: Incompatible conditional operand types Circle and Triangle

4. 개체 유형 과 함께 instanceof 사용

Java에서 모든 클래스는 Object 클래스 에서 암시 적으로 상속됩니다 . 따라서 Object 유형 과 함께 instanceof 연산자를 사용 하면 항상 true로 평가됩니다 .

@Test public void givenWhenTypeIsOfObjectType_thenReturnTrue() { Thread thread = new Thread(); Assert.assertTrue(thread instanceof Object); }

5. 개체가 null 일 때 instanceof 연산자 사용

null 인 객체에 instanceof 연산자를 사용하면 false를 반환합니다 . 또한 instanceof 연산자를 사용할 때 null 검사가 필요하지 않습니다 .

@Test public void givenWhenInstanceValueIsNull_thenReturnFalse() { Circle circle = null; Assert.assertFalse(circle instanceof Round); }

6. instanceof 및 Generics

인스턴스 테스트 및 캐스트는 런타임시 유형 정보 검사에 의존합니다. 따라서 삭제 된 제네릭 유형과 함께 instanceof 를 사용할 수 없습니다 .

예를 들어, 다음 코드 조각을 컴파일하려고하면 :

public static  void sort(List collection) { if (collection instanceof List) { // sort strings differently } // omitted }

그런 다음이 컴파일 오류가 발생합니다.

error: illegal generic type for instanceof if (collection instanceof List) { ^

기술적으로 말하자면, 우리는 reified와 함께 instanceof 만 사용할 수 있습니다.Java의 유형. 유형 정보가 런타임에 존재하면 유형이 수정됩니다.

Java에서 수정 된 유형은 다음과 같습니다.

  • int 와 같은 기본 유형
  • 비 제네릭 클래스 및 String 또는 Random 과 같은 인터페이스
  • 모든 유형이 Set 또는 Map 과 같은 제한되지 않은 와일드 카드 인 일반 유형
  • List 또는 HashMap 과 같은 원시 유형
  • String [], List [] 또는 Map [] 과 같은 다른 수정 가능한 유형의 배열

제네릭 유형 매개 변수는 수정되지 않았기 때문에 다음과 같이 사용할 수 없습니다.

public static  boolean isOfType(Object input) { return input instanceof T; // won't compile }

그러나 List 와 같은 것에 대해 테스트 할 수 있습니다 .

if (collection instanceof List) { // do something }

7. 결론

이 튜토리얼에서는 instanceof 연산자와 사용 방법에 대해 배웠습니다 . 전체 코드 샘플은 GitHub에서 사용할 수 있습니다.