객체의 타입을 확인하는 데는 instanceof를 활용하면 쉽게 파악할 수 있다. 기본적으로 instanceof는 타입을 확인하는데 공변이 적용된다. 그래서
A instanceof B 라고 한다면 A는 B와 같은 타입이거나 하위타입입니까? 물어보는것과 같다.
String a = "hello";
이런 코드가 있다고 가정하자. a의 타입은 String이다. 그래서
a instanceof String ==> true 로 자명하다. 그러나 이런 경우도 있을 수 있다.
class Person {
private String name;
private int age;
}
여기서 Person의 name과 age 타입을 동적으로 파악하기 위해 reflection을 활용한다고 하자. 그렇다면 다음과 같이 Field에 대한 정보를 가져올 수 있다.
public static void main(String[] args) {
Class<?> clazz = Person.class;
Field[] fields = clazz.getDeclareFields();
for (Field field : fields) {
Class<?> type = field.getType();
if (type instanceof String) {
// ...
}
}
}
reflection을 활용하다보면 field의 type을 확인할 일이 있을 수 있다. 위의 코드는 reflection을 활용해 Person을 구성하고 있는 field의 타입을 확인하려고 하는데 instanceof String으로 했다. 이것은 문제가 있다. type은 Type 타입이기 때문에 String 타입과 전혀 관계가 없기 때문이다. 그렇기 때문에 instanceof로는 이런 문제를 해결할 수 없다.
reflection의 Type은 실제 field의 타입 정보를 저장하고 있는데 이 때문에 Class.isAssignableFrom(확인할 타입)을 입력하면 Class 타입의 실제 타입 정보를 파악할 수 있다.
public static void main(String[] args) {
Class<?> clazz = Person.class;
Field[] fields = clazz.getDeclareFields();
for (Field field : fields) {
Class<?> type = field.getType();
if (String.class.isAssignableFrom(type)) {
// ...
}
}
}
위에서 String.class.isAssignableFrom(type)으로 해당 메서드를 사용했다. 이 메서드는 instanceof와 반대방향으로 동작한다고 보면 된다. 인자에 들어간 type이 String.class의 하위 타입이니? 라고 물어보는 것이다.
실제 reflection을 활용해서 필드의 타입과 name 정보를 파악해서 자동화할 일이 생겼는데 instanceof와 Class.isAssignableFrom(targetType)과 헷갈릴 일이 있을것 같아 정리해 두었다.
보통 instance의 타입을 확인할 때는 instanceof를 활용하고
Class의 타입을 확인할 때는 Class.isAssignableFrom을 활용하자