/* * Copyright 2011-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kr.debop4j.core.tools; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import static kr.debop4j.core.Guard.shouldNotBeNull; /** * Reflection 관련 Utility Class 입니다. * * @author 배성혁 ( sunghyouk.bae@gmail.com ) * @since 12. 9. 12 */ @Slf4j public final class ReflectTool { /** 생성자 */ private ReflectTool() {} /** * 객체가 Generic 형식일 경우, 형식인자(type parameter)들을 가져옵니다. * * @param x 검사할 객체 * @return 객체가 Generic 형식인 경우, 형식인자의 배열, Generic이 아니면 빈 배열을 반환 */ public static Type[] getParameterTypes(final Object x) { shouldNotBeNull(x, "x"); if (log.isDebugEnabled()) log.debug("객체가 Generic 수형이라면 모든 형식인자들을 가져옵니다. clazz=[{}]", x.getClass().getName()); try { ParameterizedType ptype = (ParameterizedType) x.getClass().getGenericSuperclass(); assert ptype != null : "지정된 객체가 generic 형식이 아닙니다."; return ptype.getActualTypeArguments(); } catch (Exception e) { log.warn("Generic 형식의 객체로부터 인자 수형들을 추출하는데 실패했습니다.", e); return new Type[0]; } } /** * 인스턴스가 Generic 형식이라면 첫번째 Type parameter의 수형을 반환한다. * * @param x the x * @param <T> 수형 * @return the generic parameter type */ public static <T> Class<T> getGenericParameterType(final Object x) { return getGenericParameterType(x, 0); } /** * 인스턴스가 Generic 형식이라면 index+1 번째 Type parameter의 수형을 반환한다. * * @param x the x * @param index the index * @param <T> 반환할 수형 * @return the generic parameter type */ @SuppressWarnings("unchecked") public static <T> Class<T> getGenericParameterType(final Object x, final int index) { shouldNotBeNull(x, "x"); if (log.isDebugEnabled()) log.debug("인스턴스 [{}]의 [{}] 번째 제너릭 인자 수형을 찾습니다.", x.getClass().getName(), index); Type[] types = getParameterTypes(x); if (types != null && types.length > index) { return (Class<T>) types[index]; } throw new UnsupportedOperationException("Generic 형식의 객체로부터 인자 수형들을 추출하는데 실패했습니다."); } /** * 수형이 primitive type 과 호환된다면 Primitive type으로 변경합니다. * * @param clazz the clazz * @return class */ public static Class toPrimitiveType(final Class<?> clazz) { if (clazz == Boolean.class) { return Boolean.TYPE; } if (clazz == Character.class) { return Character.TYPE; } if (clazz == Byte.class) { return Byte.TYPE; } if (clazz == Short.class) { return Short.TYPE; } if (clazz == Integer.class) { return Integer.TYPE; } if (clazz == Long.class) { return Long.TYPE; } if (clazz == Float.class) { return Float.TYPE; } if (clazz == Double.class) { return Double.TYPE; } return clazz; } }