GenericsUtil { protected static Class<? extends Object> resolveTypeVariable(Type type, List<ParameterizedType> ancestorTypeList) throws IllegalStateException { if (isNotTypeVariable(type)) { return getRawClass(type); } TypeVariable<?> targetType = (TypeVariable<?>) type; Type actualType = null; for (int i = ancestorTypeList.size() - 1; i >= 0; i--) { ParameterizedType ancestorType = ancestorTypeList.get(i); GenericDeclaration declaration = targetType.getGenericDeclaration(); if (!(declaration instanceof Class)) { throw new IllegalStateException("TypeVariable(" + targetType .getName() + " is not declared at Class " + "(ie. is declared at Method or Constructor)"); } Class<?> declaredClass = (Class<?>) declaration; if (declaredClass != ancestorType.getRawType()) { continue; } Type[] parameterTypes = declaredClass.getTypeParameters(); int index = ArrayUtils.indexOf(parameterTypes, targetType); if (index == -1) { throw new IllegalStateException("Class(" + declaredClass .getName() + ") does not declare TypeValidable(" + targetType.getName() + ")"); } actualType = ancestorType.getActualTypeArguments()[index]; if (log.isDebugEnabled()) { log.debug("resolved " + targetType.getName() + " -> " + actualType); } if (isNotTypeVariable(actualType)) { return getRawClass(actualType); } targetType = (TypeVariable<?>) actualType; } throw new IllegalStateException("Concrete type of Type(" + type + ") was not found in ancestorList(" + ancestorTypeList + ")"); }  @SuppressWarnings("rawtypes") static Class[] resolveParameterizedClass(Class<T> genericClass,
            Class<? extends T> descendantClass); static Class<? extends Object> resolveParameterizedClass(
            Class<T> genericClass, Class<? extends T> descendantClass,
            int index);  }
@Test public void testResolveTypeVariable01() throws Exception { Class<String> stringClass = String.class; Class<?> result = GenericsUtil.resolveTypeVariable(stringClass, new ArrayList<ParameterizedType>()); assertSame(stringClass, result); }
@Test public void testResolveTypeVariable02() throws Exception { Type type = getTypeVariable(AbstractList.class, GenericsUtil_ArrayListStub01.class, 0); List<ParameterizedType> list = new ArrayList<ParameterizedType>(); try { GenericsUtil.resolveTypeVariable(type, list); fail("例外が発生しませんでした。"); } catch (IllegalStateException e) { assertEquals("Concrete type of Type(" + type + ") was not found in ancestorList(" + list + ")", e .getMessage()); assertEquals(IllegalStateException.class.getName(), e.getClass() .getName()); } }
@Test public void testResolveTypeVariable03() throws Exception { try { GenericsUtil.resolveTypeVariable( new GenericsUtil_GenericArrayTypeStub03(), new ArrayList<ParameterizedType>()); fail("例外が発生しませんでした。"); } catch (IllegalStateException e) { assertNotNull(e); assertEquals(IllegalStateException.class.getName(), e.getClass() .getName()); } }
@Test public void testResolveTypeVariable04() throws Exception { Method emptyListMethod = Collections.class.getMethod("emptyList", new Class[0]); TypeVariable<?> type = emptyListMethod.getTypeParameters()[0]; List<ParameterizedType> list = getParameterizedClassList(List.class, GenericsUtil_ArrayListStub01.class); try { GenericsUtil.resolveTypeVariable(type, list); fail("例外が発生しませんでした。"); } catch (IllegalStateException e) { assertEquals("TypeVariable(" + type.getName() + " is not declared at Class " + "(ie. is declared at Method or Constructor)", e .getMessage()); assertEquals(IllegalStateException.class.getName(), e.getClass() .getName()); } }
@Test public void testResolveTypeVariable05() throws Exception { Type type = getTypeVariable(AbstractList.class, GenericsUtil_ArrayListStub01.class, 0); List<ParameterizedType> list = getParameterizedClassList(List.class, GenericsUtil_ArrayListStub01.class); list.add((ParameterizedType) Integer.class.getGenericInterfaces()[0]); Class<?> result = GenericsUtil.resolveTypeVariable(type, list); assertEquals(Map.class, result); }
@Test public void testResolveTypeVariable06() throws Exception { Type type = getTypeVariable(HashMap.class, GenericsUtil_HashMapStub02.class, 1); List<ParameterizedType> list = getParameterizedClassList(Map.class, GenericsUtil_HashMapStub02.class); Class<?> result = GenericsUtil.resolveTypeVariable(type, list); assertEquals(Integer.class, result); }