1 /* 2 * Copyright (c) 2003, 2004, 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.reflect.GenericDeclaration; 29 import java.lang.reflect.Type; 30 import java.lang.reflect.TypeVariable; 31 32 import sun.reflect.generics.factory.GenericsFactory; 33 import sun.reflect.generics.tree.FieldTypeSignature; 34 import sun.reflect.generics.visitor.Reifier; 35 36 /** 37 * Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface 38 * for core reflection. 39 */ 40 public class TypeVariableImpl<D extends GenericDeclaration> 41 extends LazyReflectiveObjectGenerator implements TypeVariable<D> { 42 D genericDeclaration; 43 private String name; 44 // upper bounds - evaluated lazily 45 private Type[] bounds; 46 47 // The ASTs for the bounds. We are required to evaluate the bounds 48 // lazily, so we store these at least until we are first asked 49 // for the bounds. This also neatly solves the 50 // problem with F-bounds - you can't reify them before the formal 51 // is defined. 52 private FieldTypeSignature[] boundASTs; 53 54 // constructor is private to enforce access through static factory 55 private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs, 56 GenericsFactory f) { 57 super(f); 58 genericDeclaration = decl; 59 name = n; 60 boundASTs = bs; 61 } 62 63 // Accessors 64 65 // accessor for ASTs for bounds. Must not be called after 66 // bounds have been evaluated, because we might throw the ASTs 67 // away (but that is not thread-safe, is it?) 68 private FieldTypeSignature[] getBoundASTs() { 69 // check that bounds were not evaluated yet 70 assert(bounds == null); 71 return boundASTs; 72 } 73 74 /** 75 * Factory method. 76 * @param decl - the reflective object that declared the type variable 77 * that this method should create 78 * @param name - the name of the type variable to be returned 79 * @param bs - an array of ASTs representing the bounds for the type 80 * variable to be created 81 * @param f - a factory that can be used to manufacture reflective 82 * objects that represent the bounds of this type variable 83 * @return A type variable with name, bounds, declaration and factory 84 * specified 85 */ 86 public static <T extends GenericDeclaration> 87 TypeVariableImpl<T> make(T decl, String name, 88 FieldTypeSignature[] bs, 89 GenericsFactory f) { 90 return new TypeVariableImpl<T>(decl, name, bs, f); 91 } 92 93 94 /** 95 * Returns an array of <tt>Type</tt> objects representing the 96 * upper bound(s) of this type variable. Note that if no upper bound is 97 * explicitly declared, the upper bound is <tt>Object</tt>. 98 * 99 * <p>For each upper bound B: 100 * <ul> 101 * <li>if B is a parameterized type or a type variable, it is created, 102 * (see {@link #ParameterizedType} for the details of the creation 103 * process for parameterized types). 104 * <li>Otherwise, B is resolved. 105 * </ul> 106 * 107 * @throws <tt>TypeNotPresentException</tt> if any of the 108 * bounds refers to a non-existent type declaration 109 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 110 * bounds refer to a parameterized type that cannot be instantiated 111 * for any reason 112 * @return an array of Types representing the upper bound(s) of this 113 * type variable 114 */ 115 public Type[] getBounds() { 116 // lazily initialize bounds if necessary 117 if (bounds == null) { 118 FieldTypeSignature[] fts = getBoundASTs(); // get AST 119 // allocate result array; note that 120 // keeping ts and bounds separate helps with threads 121 Type[] ts = new Type[fts.length]; 122 // iterate over bound trees, reifying each in turn 123 for ( int j = 0; j < fts.length; j++) { 124 Reifier r = getReifier(); 125 fts[j].accept(r); 126 ts[j] = r.getResult(); 127 } 128 // cache result 129 bounds = ts; 130 // could throw away bound ASTs here; thread safety? 131 } 132 return bounds.clone(); // return cached bounds 133 } 134 135 /** 136 * Returns the <tt>GenericDeclaration</tt> object representing the 137 * generic declaration that declared this type variable. 138 * 139 * @return the generic declaration that declared this type variable. 140 * 141 * @since 1.5 142 */ 143 public D getGenericDeclaration(){ 144 return genericDeclaration; 145 } 146 147 148 /** 149 * Returns the name of this type variable, as it occurs in the source code. 150 * 151 * @return the name of this type variable, as it appears in the source code 152 */ 153 public String getName() { return name; } 154 155 public String toString() {return getName();} 156 157 @Override 158 public boolean equals(Object o) { 159 if (o instanceof TypeVariable) { 160 TypeVariable<?> that = (TypeVariable<?>) o; 161 162 GenericDeclaration thatDecl = that.getGenericDeclaration(); 163 String thatName = that.getName(); 164 165 return 166 (genericDeclaration == null ? 167 thatDecl == null : 168 genericDeclaration.equals(thatDecl)) && 169 (name == null ? 170 thatName == null : 171 name.equals(thatName)); 172 173 } else 174 return false; 175 } 176 177 @Override 178 public int hashCode() { 179 return genericDeclaration.hashCode() ^ name.hashCode(); 180 } 181 }