1 /* 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.reflect.generics.reflectiveObjects; 27 28 import java.lang.annotation.Annotation; 29 import java.lang.reflect.Array; 30 import java.lang.reflect.GenericDeclaration; 31 import java.lang.reflect.Type; 32 import java.lang.reflect.TypeVariable; 33 import java.util.Objects; 34 35 import sun.reflect.generics.factory.GenericsFactory; 36 import sun.reflect.generics.tree.FieldTypeSignature; 37 import sun.reflect.generics.visitor.Reifier; 38 39 /** 40 * Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface 41 * for core reflection. 42 */ 43 public class TypeVariableImpl<D extends GenericDeclaration> 44 extends LazyReflectiveObjectGenerator implements TypeVariable<D> { 45 D genericDeclaration; 46 private String name; 47 // upper bounds - evaluated lazily 48 private Type[] bounds; 49 50 // The ASTs for the bounds. We are required to evaluate the bounds 51 // lazily, so we store these at least until we are first asked 52 // for the bounds. This also neatly solves the 53 // problem with F-bounds - you can't reify them before the formal 54 // is defined. 55 private FieldTypeSignature[] boundASTs; 56 57 // constructor is private to enforce access through static factory 58 private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs, 59 GenericsFactory f) { 60 super(f); 61 genericDeclaration = decl; 62 name = n; 63 boundASTs = bs; 64 } 65 66 // Accessors 67 68 // accessor for ASTs for bounds. Must not be called after 69 // bounds have been evaluated, because we might throw the ASTs 70 // away (but that is not thread-safe, is it?) 71 private FieldTypeSignature[] getBoundASTs() { 72 // check that bounds were not evaluated yet 73 assert(bounds == null); 74 return boundASTs; 75 } 76 77 /** 78 * Factory method. 79 * @param decl - the reflective object that declared the type variable 80 * that this method should create 81 * @param name - the name of the type variable to be returned 82 * @param bs - an array of ASTs representing the bounds for the type 83 * variable to be created 84 * @param f - a factory that can be used to manufacture reflective 85 * objects that represent the bounds of this type variable 86 * @return A type variable with name, bounds, declaration and factory 87 * specified 88 */ 89 public static <T extends GenericDeclaration> 90 TypeVariableImpl<T> make(T decl, String name, 91 FieldTypeSignature[] bs, 92 GenericsFactory f) { 93 return new TypeVariableImpl<T>(decl, name, bs, f); 94 } 95 96 97 /** 98 * Returns an array of <tt>Type</tt> objects representing the 99 * upper bound(s) of this type variable. Note that if no upper bound is 100 * explicitly declared, the upper bound is <tt>Object</tt>. 101 * 102 * <p>For each upper bound B: 103 * <ul> 104 * <li>if B is a parameterized type or a type variable, it is created, 105 * (see {@link #ParameterizedType} for the details of the creation 106 * process for parameterized types). 107 * <li>Otherwise, B is resolved. 108 * </ul> 109 * 110 * @throws <tt>TypeNotPresentException</tt> if any of the 111 * bounds refers to a non-existent type declaration 112 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 113 * bounds refer to a parameterized type that cannot be instantiated 114 * for any reason 115 * @return an array of Types representing the upper bound(s) of this 116 * type variable 117 */ 118 public Type[] getBounds() { 119 // lazily initialize bounds if necessary 120 if (bounds == null) { 121 FieldTypeSignature[] fts = getBoundASTs(); // get AST 122 // allocate result array; note that 123 // keeping ts and bounds separate helps with threads 124 Type[] ts = new Type[fts.length]; 125 // iterate over bound trees, reifying each in turn 126 for ( int j = 0; j < fts.length; j++) { 127 Reifier r = getReifier(); 128 fts[j].accept(r); 129 ts[j] = r.getResult(); 130 } 131 // cache result 132 bounds = ts; 133 // could throw away bound ASTs here; thread safety? 134 } 135 return bounds.clone(); // return cached bounds 136 } 137 138 /** 139 * Returns the <tt>GenericDeclaration</tt> object representing the 140 * generic declaration that declared this type variable. 141 * 142 * @return the generic declaration that declared this type variable. 143 * 144 * @since 1.5 145 */ 146 public D getGenericDeclaration(){ 147 return genericDeclaration; 148 } 149 150 151 /** 152 * Returns the name of this type variable, as it occurs in the source code. 153 * 154 * @return the name of this type variable, as it appears in the source code 155 */ 156 public String getName() { return name; } 157 158 public String toString() {return getName();} 159 160 @Override 161 public boolean equals(Object o) { 162 if (o instanceof TypeVariable) { 163 TypeVariable<?> that = (TypeVariable<?>) o; 164 165 GenericDeclaration thatDecl = that.getGenericDeclaration(); 166 String thatName = that.getName(); 167 168 return 169 (genericDeclaration == null ? 170 thatDecl == null : 171 genericDeclaration.equals(thatDecl)) && 172 (name == null ? 173 thatName == null : 174 name.equals(thatName)); 175 176 } else 177 return false; 178 } 179 180 @Override 181 public int hashCode() { 182 return genericDeclaration.hashCode() ^ name.hashCode(); 183 } 184 185 // Currently vacuous implementations of AnnotatedElement methods. 186 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { 187 Objects.requireNonNull(annotationClass); 188 return false; 189 } 190 191 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 192 Objects.requireNonNull(annotationClass); 193 return null; 194 } 195 196 public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { 197 Objects.requireNonNull(annotationClass); 198 return null; 199 } 200 201 @SuppressWarnings("unchecked") 202 public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) { 203 Objects.requireNonNull(annotationClass); 204 // safe because annotationClass is the class for T 205 return (T[])Array.newInstance(annotationClass, 0); 206 } 207 208 @SuppressWarnings("unchecked") 209 public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass) { 210 Objects.requireNonNull(annotationClass); 211 // safe because annotationClass is the class for T 212 return (T[])Array.newInstance(annotationClass, 0); 213 } 214 215 public Annotation[] getAnnotations() { 216 // Since zero-length, don't need defensive clone 217 return EMPTY_ANNOTATION_ARRAY; 218 } 219 220 public Annotation[] getDeclaredAnnotations() { 221 // Since zero-length, don't need defensive clone 222 return EMPTY_ANNOTATION_ARRAY; 223 } 224 225 private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; 226 }