Java에서 사용되는 'instanceof'연산자는 무엇입니까?


163

instanceof운영자 는 무엇을 사용합니까? 나는 물건을 보았다

if (source instanceof Button) {
    //...
} else {
    //...
}

그러나 그 어느 것도 나에게 의미가 없었습니다. 나는 연구를했지만 아무 설명없이 예제 만 생각해 냈습니다.


38
여기서 질문하는 데 아무런 문제가 없지만 Java를 배우는 경우 책을 원할 수 있습니다. 괜찮은 Java 책은이 질문에 대한 대답과 다음 1000 가지를 가질 것입니다.
제임스 K. 포크 대통령

이러한 운영자는 많은 특정 용도를 가지고 있습니다. 이해가되지 않는 예 중 하나에 대한 설명을 요청한 경우에는 구체적인 질문이 될 것입니다.
Raedwald

2
아래의 답변은 정확하지만 instanceof는 10에서 9 번 과다 사용 된 연산자이며 다형성의 적절한 사용 (항상은 아니지만 종종)으로 대체 될 수 있습니다.
Richard Tingle

Richard보다 한 가지 더 나아갈 것입니다. instanceof를 올바르게 사용하는 것을 본 적이 없습니다. 잘못 설계된 코드를 기반으로 빠른 해킹에만 유용합니다. OOP가 마음에 들지 않으면 다른 언어로 작성하십시오 (많음). instanceof에 "아니오"라고 말하십시오!
Scott Biggs

5
@ScottBiggs instanceof재정의 할 때 좋은 대안이 equals있습니까?
Ben Aaronson

답변:


228

instanceof키워드는 객체 (인스턴스)가 지정된 유형의 하위 유형 인지 테스트하는 데 사용되는 이진 연산자 입니다.

상상해보십시오.

interface Domestic {}
class Animal {}
class Dog extends Animal implements Domestic {}
class Cat extends Animal implements Domestic {}

으로 만든 dog 객체를 상상해보십시오 Object dog = new Dog().

dog instanceof Domestic // true - Dog implements Domestic
dog instanceof Animal   // true - Dog extends Animal
dog instanceof Dog      // true - Dog is Dog
dog instanceof Object   // true - Object is the parent type of all objects

그러나,와 Object animal = new Animal();,

animal instanceof Dog // false

왜냐하면 "정제 된" Animal의 수퍼 타입 이기 때문 입니다 Dog.

과,

dog instanceof Cat // does not even compile!

Dog하위 유형도 아니고 수퍼 유형도 아니기 때문에 Cat구현하지도 않습니다.

dog위에서 사용 된 변수 는 유형 Object입니다. 이것은 런타임 작업 instanceof임을 보여주고 런타임 에 객체 유형에 따라 다르게 반응 하는 유스 케이스 를 제공합니다 .

참고 사항 : expressionThatIsNull instanceof T모든 유형에 대해 false입니다 T.

행복한 코딩.


14
방금 시도했습니다 Object dog = new Dog(); System.out.println(dog instanceof Cat);. 이것은 잘 컴파일되고 인쇄 false됩니다. 컴파일러는 컴파일 타임 dog에 Cat이 될 수없는 컴파일 시간을 결정할 수 없습니다 (JLS의 규칙에 따라)
Erwin Bolwidt

@ErwinBolwidt 당신이 그것을 시도했을 때 실수했습니다. 궁금한 사람 : JLS 섹션 15.20.2가 찾고 있습니다. 최소한의 작동하지 않는 예 :boolean b = "foo" instanceof Integer;
Felix S

3
@FelixS 답을 다시 읽어야합니다. 대답은 Object indirect = ...; if (indirect instanceof Something)입니다. if (literal instanceof Something)당신이 가정하는 것처럼 보이지 않습니다 .
Erwin Bolwidt

1
@ ErwinBolwidt 아, 맞아, 나는 그 Object dog부분 을 건너 뛰어야했다 . 내 잘못이야!
Felix S

dog instanceof Cat // does not even compile!(수업이기 때문에). 경우 Cat인터페이스 있었다 다음 컴파일합니다.
Hamza Belmellouki 2016 년

44

표현식의 왼쪽이 인스턴스 인 경우 true를 리턴하는 연산자 입니다. 이 클래스 이름 .

이런 식으로 생각하십시오. 블록의 모든 집들이 같은 청사진으로 지어 졌다고 가정 해 봅시다. 10 개의 주택 (객체), 1 세트의 청사진 (클래스 정의).

instanceof개체 모음이 있고 그 개체가 무엇인지 확실하지 않은 경우 유용한 도구입니다. 폼에 컨트롤 모음이 있다고 가정 해 봅시다. 어떤 확인란이 있는지 확인한 상태를 읽으려고하지만 일반 상태의 객체에 체크 된 상태를 요청할 수는 없습니다. 대신, 각 객체가 확인란인지 확인하고, 그렇다면 객체를 확인란으로 캐스트하고 속성을 확인하십시오.

if (obj instanceof Checkbox)
{
    Checkbox cb = (Checkbox)obj;
    boolean state = cb.getState();
}

15
즉, 사용 instanceof하면 다운 캐스트하는 것이 안전 할 수 있습니다.
Raedwald

29

이 사이트 에 설명 된대로 :

instanceof객체 특정 형인 경우 작업자는 검사에 사용될 수있다 ..

if (objectReference instanceof type)

간단한 예 :

String s = "Hello World!"
return s instanceof String;
//result --> true

그러나 instanceof널 참조 변수 / 표현식에 적용 하면 false가 리턴됩니다.

String s = null;
return s instanceof String;
//result --> false

서브 클래스는 수퍼 클래스의 '유형'이므로이를 사용하여 instanceof이를 확인할 수 있습니다 .

class Parent {
    public Parent() {}
}

class Child extends Parent {
    public Child() {
        super();
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        System.out.println( child instanceof Parent );
    }
}
//result --> true

이게 도움이 되길 바란다!


15

이 연산자를 사용하면 객체 유형을 결정할 수 있습니다. 그것은boolean값을 합니다.

예를 들어

package test;

import java.util.Date;
import java.util.Map;
import java.util.HashMap;

public class instanceoftest
{
    public static void main(String args[])
    {
        Map m=new HashMap();
        System.out.println("Returns a boolean value "+(m instanceof Map));
        System.out.println("Returns a boolean value "+(m instanceof HashMap));
        System.out.println("Returns a boolean value "+(m instanceof Object));
        System.out.println("Returns a boolean value "+(m instanceof Date));
    }
} 

출력은 다음과 같습니다

Returns a boolean value true
Returns a boolean value true
Returns a boolean value true
Returns a boolean value false


4

다른 답변에서 언급했듯이 일반적인 표준 사용법은 instanceof식별자가보다 구체적인 유형을 참조하는지 확인하는 것입니다. 예:

Object someobject = ... some code which gets something that might be a button ...
if (someobject instanceof Button) {
    // then if someobject is in fact a button this block gets executed
} else {
    // otherwise execute this block
}

그러나 왼쪽 표현식의 유형 은 오른쪽 표현식 의 상위 유형이어야합니다 ( JLS 15.20.2Java Puzzlers, # 50, pp114 참조 ). 예를 들어 다음은 컴파일에 실패합니다.

public class Test {
    public static void main(String [] args) {
        System.out.println(new Test() instanceof String); // will fail to compile
    }
}

이 메시지와 함께 컴파일에 실패합니다 :

Test.java:6: error: inconvertible types
        System.out.println(t instanceof String);
                       ^
  required: String
  found:    Test
1 error

으로는 Test의 부모 클래스되지 않습니다 String. OTOH, 이것은 완벽하게 컴파일 false되고 예상대로 인쇄 됩니다.

public class Test {
    public static void main(String [] args) {
        Object t = new Test();
        // compiles fine since Object is a parent class to String
        System.out.println(t instanceof String); 
    }
}

사양에 연결해 주셔서 감사합니다!
jpaugh

1
public class Animal{ float age; }

public class Lion extends Animal { int claws;}

public class Jungle {
    public static void main(String args[]) {

        Animal animal = new Animal(); 
        Animal animal2 = new Lion(); 
        Lion lion = new Lion(); 
        Animal animal3 = new Animal(); 
        Lion lion2 = new Animal();   //won't compile (can't reference super class object with sub class reference variable) 

        if(animal instanceof Lion)  //false

        if(animal2 instanceof Lion)  //true

        if(lion insanceof Lion) //true

        if(animal3 instanceof Animal) //true 

    }
}

1

평등 검사에서 속기로 사용할 수 있습니다.

이 코드는

if(ob != null && this.getClass() == ob.getClass) {
}

로 쓸 수 있습니다

if(ob instanceOf ClassA) {
}

1

대부분의 사람들은이 질문의 "무엇"을 올바르게 설명했지만 아무도 "어떻게"를 올바르게 설명하지 않았습니다.

여기 간단한 그림이 있습니다 :

String s = new String("Hello");
if (s instanceof String) System.out.println("s is instance of String"); // True
if (s instanceof Object) System.out.println("s is instance of Object"); // True
//if (s instanceof StringBuffer) System.out.println("s is instance of StringBuffer"); // Compile error
Object o = (Object)s;
if (o instanceof StringBuffer) System.out.println("o is instance of StringBuffer"); //No error, returns False
else System.out.println("Not an instance of StringBuffer"); // 
if (o instanceof String) System.out.println("o is instance of String"); //True

출력 :

s is instance of String
s is instance of Object
Not an instance of StringBuffer
o is instance of String

sStringBuffer와 비교할 때 컴파일러 오류의 이유 는 docs에 잘 설명되어 있습니다 .

객체를 사용하여 클래스의 인스턴스, 서브 클래스의 인스턴스 또는 특정 인터페이스를 구현하는 클래스의 인스턴스인지 테스트 할 수 있습니다.

이는 LHS가 RHS의 인스턴스이거나 RHS를 구현하거나 RHS를 확장하는 클래스 여야 함을 의미합니다.

그렇다면 instanceof를 사용하는 방법?
모든 클래스는 객체를 확장하므로 객체에 대한 유형 캐스팅 LHS는 항상 당신에게 유리합니다.

String s = new String("Hello");
if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //No compiler error now :)
else System.out.println("Not an instance of StringBuffer");

출력 :

Not an instance of StringBuffer

마지막 예제에서 "StringBuffer의 인스턴스가 아님"을 반환하는 이유는 무엇입니까? LHS의 Object에 s를 캐스트하고 RHS의 인스턴스인지 확인하기 때문에 s를 Object에 if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //shouldn't this be truetypecasting하고 있습니까?
sofs1

s는 String 객체에 대한 참조이므로 (Java는 C ++과 달리 동적 다형성을 사용함) String은 StringBuffer의 하위 클래스가 아닙니다.
sziraqui


0

키워드 인스턴스는 특정 객체의 인스턴스를 알고 싶을 때 유용합니다.

예외가 발생하고 catch 할 때 합계 사용자 정의 작업을 수행 한 다음 논리 (throw 또는 log 등)에 따라 다시 계속한다고 가정하십시오.

예 : 1) 사용자가 사용자 정의 예외 "InvalidExtensionsException"을 작성하여 로직별로 처리합니다.

2) 이제 catch 블록 catch (예외 e) {예외 유형이 "InvalidExtensionsException"인 경우 합계 논리 수행

InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3) 인스턴스를 확인하지 않고 예외 유형이 널 포인터 예외 인 경우 코드가 중단됩니다.

따라서 논리는 if 인스턴스 (예 : InvalidExtensionsException)의 내부에 있어야합니다. {InvalidExtensionsException InvalidException = (InvalidExtensionsException) e; }

위의 예제는 잘못된 코딩 방법입니다. 그러나이 예제는 인스턴스 사용을 이해하는 데 도움이됩니다.


0

가장 좋은 설명은 jls 입니다. 항상 출처가 무엇인지 확인하십시오. 최고의 답변과 더 많은 정보를 얻을 수 있습니다. 여기에 일부 부분을 재현 :

instanceof 연산자의 RelationalExpression 피연산자의 유형은 참조 유형 또는 널 유형이어야합니다. 그렇지 않으면 컴파일 타임 오류가 발생합니다.

instanceof 연산자 다음에 언급 된 ReferenceType이 수정 가능한 참조 유형을 나타내지 않으면 컴파일 타임 오류입니다 (§4.7).

ReferenceType에 대한 RelationalExpression의 캐스트 (§15.16)가 컴파일 타임 오류로 거부되면 관계형 표현식의 인스턴스도 컴파일 타임 오류를 생성합니다. 이러한 상황에서 표현의 인스턴스의 결과는 결코 사실이 될 수 없습니다.


0

java instanceof연산자는 오브젝트가 지정된 유형 (클래스 또는 서브 클래스 또는 인터페이스)의 인스턴스인지 테스트하는 데 사용됩니다.

Java comparison operator에서 instanceof는 유형과 인스턴스를 비교 하므로 유형이라고도 합니다. 이 중 하나를 반환 true하거나 false. 값 instanceof이있는 변수를 사용 하여 연산자를 적용하면nullfalse .

JEP 305 가 포함 된 JDK 14+에서 "패턴 일치"를 수행 할 수도 있습니다.instanceof

패턴은 기본적으로 값에 특정 유형이 있는지 테스트하고 값이 일치하는 유형에있을 때 값에서 정보를 추출 할 수 있습니다. 패턴 일치를 통해 시스템에서 공통 논리를보다 명확하고 효율적으로 표현할 수 있습니다. 즉, 객체에서 구성 요소를 조건부로 제거합니다.

자바 14 이전

if (obj instanceof String) {
    String str = (String) obj; // need to declare and cast again the object
    .. str.contains(..) ..
}else{
     str = ....
}

Java 14 향상

if (!(obj instanceof String str)) {
    .. str.contains(..) .. // no need to declare str object again with casting
} else {
    .. str....
}

타입 체크와 다른 조건을 함께 결합 할 수도 있습니다

if (obj instanceof String str && str.length() > 4) {.. str.contains(..) ..}

패턴 일치를 instanceof사용하면 Java 프로그램에서 전체 명시 적 캐스트 수가 줄어 듭니다.

PS : instanceOf개체가 null이 아닌 경우에만 일치하며에 할당 할 수 있습니다 str.


-1
class Test48{
public static void main (String args[]){
Object Obj=new Hello();
//Hello obj=new Hello;
System.out.println(Obj instanceof String);
System.out.println(Obj instanceof Hello);
System.out.println(Obj instanceof Object);
Hello h=null;
System.out.println(h instanceof Hello);
System.out.println(h instanceof Object);
}
}  

1
코드에만 답변을 게시하지 마십시오. 계속해서 설명을 추가하십시오.
L. Guthardt

-2

매우 간단한 코드 예제 :

If (object1 instanceof Class1) {
   // do something
} else if (object1 instanceof Class2) {
   // do something different
}

여기서 조심하십시오. 위의 예에서 Class1이 Object 인 경우 첫 번째 비교는 항상 참입니다. 따라서 예외와 마찬가지로 계층 적 순서가 중요합니다!


-2

지도를 사용하여 인스턴스의 추상화를 높일 수 있습니다

private final Map<Class, Consumer<String>> actions = new HashMap<>();

그런 다음 이러한 맵을 사용하면 조치가 추가됩니다.

actions.put(String.class, new Consumer<String>() {
        @Override
        public void accept(String s) {
           System.out.println("action for String");       
        }
    };

그런 다음 알 수없는 유형의 객체를 사용하면 해당지도에서 특정 작업을 수행 할 수 있습니다

actions.get(someObject).accept(someObject)

-2

instanceof 연산자는 객체가 지정된 유형의 인스턴스인지 확인하는 데 사용됩니다. (클래스 또는 서브 클래스 또는 인터페이스).

instanceof는 인스턴스를 형식과 비교하기 때문에 형식 비교 연산자라고도합니다. true 또는 false를 반환합니다.

class Simple1 {  
public static void main(String args[]) {  
Simple1 s=new Simple1();  
System.out.println(s instanceof Simple1); //true  
}  
}  

null 값을 가진 변수로 instanceof 연산자를 적용하면 false를 반환합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.