플랫폼 코드를 개발할 때 특정 클래스의 필드를 저장하고 다뤄야할 때가 있다. 


이 때 java reflection을 이용하면 매우 유용하다. .



개발 중에 에러가 다음과 같이 발생했다. 




Exception in thread "main" java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class




에러가 발생한 부분은 다음과 같다.


public List<Map<String, String>> mapOfList;




이 문제는 generic of generic의 문제이다. 



Before


for (Class<?> modelClass : getClasses()) {

for (Field field : modelClass.getDeclaredFields()) {

Class<?> fieldType = field.getType();


if (Collection.class.isAssignableFrom(fieldType)) {

ParameterizedType fieldGenericType = (ParameterizedType) field.getGenericType();


Class<?> classOfCollection = null;

if (fieldGenericType.getActualTypeArguments().length > 0) {

Type genericType = fieldGenericType.getActualTypeArguments()[0];

if (genericType != null) {

classOfCollection = (Class<?>) genericType; // 여기서 발생했다.

}

fieldType = classOfCollection;

}

}

    //...

  }

  //..

}




다음처럼 바꾸면 제대로 동작한다. 




After



for (Class<?> modelClass : getClasses()) {

for (Field field : modelClass.getDeclaredFields()) {

Class<?> fieldType = field.getType();


if (Collection.class.isAssignableFrom(fieldType)) {

ParameterizedType fieldGenericType = (ParameterizedType) field.getGenericType();


Class<?> classOfCollection = null;

if (fieldGenericType.getActualTypeArguments().length > 0) {

Type genericType = fieldGenericType.getActualTypeArguments()[0];

if (genericType != null) {

if (genericType instanceof Class) {

classOfCollection = (Class<?>) genericType;

} else if (genericType instanceof ParameterizedType) { // supports generic of generic 

Type rawType = ((ParameterizedType) genericType).getRawType();

classOfCollection = (Class<?>) rawType;

}

}

fieldType = classOfCollection;

}

}

    //...

  }

  //..

}





Posted by '김용환'
,