본문 바로가기

JAVA/개념정리

자바/Java instanceof 연산자란?

자바/Java instanceof 연산자?




자바의 instanceof 연사자란 무엇일까요?


참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instanceof 연산자를 사용합니다. 주로 조건문에 사용되며, instanceof의 왼쪽에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치합니다. 그리고 연산의 결과로 boolean값인 true, false 중의 하나를 반환 합니다.


instanceof를 이용한 연산결과로 true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻합니다.

[참고] 값이 null인 참조변수에 대해 instanceof 연산을 수행하면 flase를 결과로 얻는다. 


1) Instanceof.java

package arabiannight.tistory.com.java.test;

public class Instanceof {

	public static void main(String[] args) {

		FireEngine f = new FireEngine();
		Ambulance a = new Ambulance();
		
		Instanceof test = new Instanceof();
		test.doWork(f);
		test.doWork(a);

	}

	public void doWork(Car c) {
		if (c instanceof FireEngine) {
			FireEngine f = (FireEngine)c;
			f.water();
			
		} else if (c instanceof Ambulance) {
			Ambulance a = (Ambulance)c;
			a.siren();
		}
	}
}



class Car {
	String color;
	int door;

	void drive() { //운전하는 기능
		System.out.println("drive, brrrr~");
	}

	void stop() { // 멈추는 기능
		System.out.println("stop!!!");
	}
}


class FireEngine extends Car {  // 소방차
	void water() {              // 물 뿌리는 기능
		System.out.println("warter!!!");
	}
}

class Ambulance extends Car {  // 앰뷸런스
	void siren() {             // 사이렌을 울리는 기능
		System.out.println("siren~~~~");
	}
}


실행결과 :
warter!!!
siren~~~~


위의 코드는 Car타입의 참조변수 c를 매개변수로 하는 메서드 입니다. 이 메서드가 호출될 때, 매개변수로 Car클래스 또는 그 자손 클래스의 인스턴스를 넘겨받겠지만 메서드 내에서는 정확히 어떤 인스턴스인지 알 길이 없습니다. 그렇기때문에 instanceof 연산자를 이용해서 참조변수 c가 가리키고 있는 인스턴스의 타입을 체크하고, 적절히 형변환한 다음에 작업을 해야 합니다.

조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있기 때문에, 참조변수의 타입과 인스턴스의 타입이 항상 일치하지는 않는다는 것을 배웠습니다. 조상타입의 참조변수로는 실제 인스턴스의 멤버들을 모두 사용할 수 없기 때문에, 실제 인스턴스와 같은 타입의 참조변수로 형변환을 해야만 인스턴스의 모든 멤버들은 사용할 수 있습니다.



2) InstanceofTest.java 

package arabiannight.tistory.com.java.test;

class InstanceofTest {
	public static void main(String args[]) {
		FireEngine f = new FireEngine();

		if(f instanceof FireEngine) {
			System.out.println("This is a FireEngine instance.");
		} 

		if(f instanceof Car) {
			System.out.println("This is a Car instance.");
		} 

		if(f instanceof Object) {
			System.out.println("This is an Object instance.");
		} 
	}
} // class

class Car {}
class FireEngine extends Car {}


실행결과 : 

This is a FireEngine instance.
This is a Car instance.
This is an Object instance.

비록 생성된 인스턴스는 FireEngine타입일지라도, Object타입과 Car타입의 instanceof 연산에서도 true를 결과로 얻었습니다. 그 이유는 FireEngine클래스는 Object클래스와 Car클래스의 자손클래스이므로 조상의 멤버들을 상속받았기 때문에, FireEngine인스턴스는 Object인스턴스와 Car인스턴스를 포함하고 있는 셈이기 때문입니다.

요약하면, 실제 인스턴스와 같은 타입의 instanceof 연산 이외의 조상타입의 instanceof 연산에도 true를 결과로 얻으며,  instanceof 연산의 결과가 ture라는 것은 검사한 타입으로의 형변환을 해도 아무런 문제가 없다는 뜻이다.


어떤 타입의 대한 instanceof 연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.






<정리>

1) 인스턴스 멤버보다 참조변수가 사용할 수 있는 멤버수가 더 많으면 사용할 수 없다.  

2) 인스턴스 멤버보다 참조변수가 사용할 수 있는 멤버수가 적으면 사용할 수 있다. (같아도 O)

그러므로 조상의 참조변수로는 모든 자손의 인스턴스를 참조 할 수 있다.

조상 참조변수 instanceof 자손 인스턴스 (무조건 O)

Object o instanceof 자손 인스턴스 (무조건 O)

2)번 예제처럼 빈 자손 Class를 만든다면

자손 참조변수 instanceof 조상 인스턴스 (가능함 O)






출처 : 자바의 정석