1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package tests.api.java.lang.reflect; 18 19 20import java.lang.reflect.Method; 21import java.lang.reflect.ParameterizedType; 22import java.lang.reflect.Type; 23import java.lang.reflect.TypeVariable; 24import java.lang.reflect.WildcardType; 25 26/** 27 * Tests bounded type parameters declared on methods and bounded wildcards. 28 */ 29public class WildcardTypeTest extends GenericReflectionTestsBase { 30 @SuppressWarnings({"unchecked", "hiding"}) 31 static class BoundedWildcardsGenericMethods<T> { 32 33 public <T extends BoundedWildcardsGenericMethods> void lowerBoundedParamNoReturn( BoundedWildcardsGenericMethods<? super T> param) {} 34 35 public <T extends BoundedWildcardsGenericMethods> void upperBoundedParamNoReturn( BoundedWildcardsGenericMethods<? extends T> param) {} 36 37 public <T extends BoundedWildcardsGenericMethods> T lowerBoundedParamReturn(BoundedWildcardsGenericMethods<? super T> param) { return (T) new Object(); } 38 39 public <T extends BoundedWildcardsGenericMethods> T upperBoundedParamReturn(BoundedWildcardsGenericMethods<? extends T> param) { return (T) new Object();} 40 } 41 42 @SuppressWarnings("unchecked") 43 private static Class<? extends BoundedWildcardsGenericMethods> clazz = BoundedWildcardsGenericMethods.class; 44 45 /** 46 * Tests that there are is one Type Parameter on the Class itself. 47 */ 48 public void testBoundedGenericMethods() { 49 assertLenghtOne(clazz.getTypeParameters()); 50 } 51 52 /** 53 * Tests whether the type parameter is bounded by BoundedGenericMethods like: 54 * <T extends BoundedGenericMethods>. 55 * @param method the declaring method 56 */ 57 private void checkBoundedTypeParameter(Method method) { 58 TypeVariable<Method> typeParameter = getTypeParameter(method); 59 assertEquals("T", typeParameter.getName()); 60 assertEquals(method, typeParameter.getGenericDeclaration()); 61 62 Type[] bounds = typeParameter.getBounds(); 63 assertLenghtOne(bounds); 64 Type bound = bounds[0]; 65 assertEquals(BoundedWildcardsGenericMethods.class, bound); 66 } 67 68 private void checkLowerBoundedParameter(Method method) { 69 Type genericParameterType = method.getGenericParameterTypes()[0]; 70 assertInstanceOf(ParameterizedType.class, genericParameterType); 71 72 ParameterizedType parameterizedType = (ParameterizedType) genericParameterType; 73 74 Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); 75 assertLenghtOne(actualTypeArguments); 76 assertInstanceOf(WildcardType.class, actualTypeArguments[0]); 77 78 WildcardType wildcardType = (WildcardType) actualTypeArguments[0]; 79 80 Type[] lowerBounds = wildcardType.getLowerBounds(); 81 assertLenghtOne(lowerBounds); 82 Type lowerBound = lowerBounds[0]; 83 assertEquals(getTypeParameter(method), lowerBound); 84 85 Type[] upperBounds = wildcardType.getUpperBounds(); 86 assertEquals(Object.class, upperBounds[0]); 87 } 88 89 private void checkUpperBoundedParameter(Method method) { 90 assertLenghtOne(method.getGenericParameterTypes()); 91 Type genericParameterType = method.getGenericParameterTypes()[0]; 92 assertInstanceOf(ParameterizedType.class, genericParameterType); 93 94 ParameterizedType parameterizedType = (ParameterizedType) genericParameterType; 95 Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); 96 assertLenghtOne(actualTypeArguments); 97 assertInstanceOf(WildcardType.class, actualTypeArguments[0]); 98 99 WildcardType wildcardType = (WildcardType) actualTypeArguments[0]; 100 assertLenghtZero(wildcardType.getLowerBounds()); 101 102 Type[] upperBounds = wildcardType.getUpperBounds(); 103 assertLenghtOne(upperBounds); 104 Type upperBound = upperBounds[0]; 105 assertEquals(getTypeParameter(method), upperBound); 106 } 107 108 @SuppressWarnings("unchecked") 109 private void checkReturnType(Method method) { 110 Type genericReturnType = method.getGenericReturnType(); 111 assertEquals(getTypeParameter(method), genericReturnType); 112 assertTrue(genericReturnType instanceof TypeVariable); 113 114 TypeVariable<Method> returnTypeVariable = (TypeVariable<Method>) genericReturnType; 115 assertEquals(method, returnTypeVariable.getGenericDeclaration()); 116 117 Type[] bounds = returnTypeVariable.getBounds(); 118 assertLenghtOne(bounds); 119 Type bound = bounds[0]; 120 121 assertEquals(BoundedWildcardsGenericMethods.class, bound); 122 } 123 124 public void testUpperBoundedParamNoReturn() throws Exception { 125 Method method = clazz.getMethod("upperBoundedParamNoReturn", BoundedWildcardsGenericMethods.class); 126 checkBoundedTypeParameter(method); 127 checkUpperBoundedParameter(method); 128 } 129 130 public void testLowerBoundedParamReturn() throws Exception { 131 Method method = clazz.getMethod("lowerBoundedParamReturn", BoundedWildcardsGenericMethods.class); 132 checkBoundedTypeParameter(method); 133 checkLowerBoundedParameter(method); 134 checkReturnType(method); 135 } 136 137 public void testUpperBoundedParamReturn() throws Exception { 138 Method method = clazz.getMethod("upperBoundedParamReturn", BoundedWildcardsGenericMethods.class); 139 checkBoundedTypeParameter(method); 140 checkUpperBoundedParameter(method); 141 checkReturnType(method); 142 } 143 144 public void testLowerBoundedParamNoReturn() throws Exception { 145 Method method = clazz.getMethod("lowerBoundedParamNoReturn", BoundedWildcardsGenericMethods.class); 146 checkBoundedTypeParameter(method); 147 assertLenghtOne(method.getGenericParameterTypes()); 148 checkLowerBoundedParameter(method); 149 } 150 151} 152