1 /* 2 * Copyright (c) 2003, 2014, 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 29 import java.lang.reflect.Type; 30 import java.lang.reflect.WildcardType; 31 import sun.reflect.generics.factory.GenericsFactory; 32 import sun.reflect.generics.tree.FieldTypeSignature; 33 import sun.reflect.generics.visitor.Reifier; 34 import java.util.Arrays; 35 36 37 /** 38 * Implementation of WildcardType interface for core reflection. 39 */ 40 public class WildcardTypeImpl extends LazyReflectiveObjectGenerator 41 implements WildcardType { 42 // upper bounds - evaluated lazily 43 private volatile Type[] upperBounds; 44 // lower bounds - evaluated lazily 45 private volatile Type[] lowerBounds; 46 // The ASTs for the bounds. We are required to evaluate the bounds 47 // lazily, so we store these until we are first asked 48 // for the bounds. This also neatly solves the 49 // problem with F-bounds - you can't reify them before the formal 50 // is defined. 51 private volatile FieldTypeSignature[] upperBoundASTs; 52 private volatile FieldTypeSignature[] lowerBoundASTs; 53 54 // constructor is private to enforce access through static factory 55 private WildcardTypeImpl(FieldTypeSignature[] ubs, 56 FieldTypeSignature[] lbs, 57 GenericsFactory f) { 58 super(f); 59 upperBoundASTs = ubs; 60 lowerBoundASTs = lbs; 61 } 62 63 /** 64 * Factory method. 65 * @param ubs - an array of ASTs representing the upper bounds for the type 66 * variable to be created 67 * @param lbs - an array of ASTs representing the lower bounds for the type 68 * variable to be created 69 * @param f - a factory that can be used to manufacture reflective 70 * objects that represent the bounds of this wildcard type 71 * @return a wild card type with the requested bounds and factory 72 */ 73 public static WildcardTypeImpl make(FieldTypeSignature[] ubs, 74 FieldTypeSignature[] lbs, 75 GenericsFactory f) { 76 return new WildcardTypeImpl(ubs, lbs, f); 77 } 78 79 /** 80 * Returns an array of <tt>Type</tt> objects representing the upper 81 * bound(s) of this type variable. Note that if no upper bound is 82 * explicitly declared, the upper bound is <tt>Object</tt>. 83 * 84 * <p>For each upper bound B : 85 * <ul> 86 * <li>if B is a parameterized type or a type variable, it is created, 87 * (see {@link #ParameterizedType} for the details of the creation 88 * process for parameterized types). 89 * <li>Otherwise, B is resolved. 90 * </ul> 91 * 92 * @return an array of Types representing the upper bound(s) of this 93 * type variable 94 * @throws <tt>TypeNotPresentException</tt> if any of the 95 * bounds refers to a non-existent type declaration 96 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 97 * bounds refer to a parameterized type that cannot be instantiated 98 * for any reason 99 */ 100 public Type[] getUpperBounds() { 101 // lazily initialize bounds if necessary 102 Type[] ts = upperBounds; 103 if (ts == null) { 104 FieldTypeSignature[] fts = upperBoundASTs; // get AST 105 if (fts == null) { 106 // race with concurrent initialization 107 ts = upperBounds; 108 assert ts != null; 109 } else { 110 // allocate result array; note that 111 // keeping ts and bounds separate helps with threads 112 ts = new Type[fts.length]; 113 // iterate over bound trees, reifying each in turn 114 for ( int j = 0; j < fts.length; j++) { 115 Reifier r = getReifier(); 116 fts[j].accept(r); 117 ts[j] = r.getResult(); 118 } 119 // cache result 120 upperBounds = ts; 121 // throw away upper bound ASTs 122 upperBoundASTs = null; 123 } 124 } 125 return ts.clone(); // return cached bounds 126 } 127 128 /** 129 * Returns an array of <tt>Type</tt> objects representing the 130 * lower bound(s) of this type variable. Note that if no lower bound is 131 * explicitly declared, the lower bound is the type of <tt>null</tt>. 132 * In this case, a zero length array is returned. 133 * 134 * <p>For each lower bound B : 135 * <ul> 136 * <li>if B is a parameterized type or a type variable, it is created, 137 * (see {@link #ParameterizedType} for the details of the creation 138 * process for parameterized types). 139 * <li>Otherwise, B is resolved. 140 * </ul> 141 * 142 * @return an array of Types representing the lower bound(s) of this 143 * type variable 144 * @throws <tt>TypeNotPresentException</tt> if any of the 145 * bounds refers to a non-existent type declaration 146 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 147 * bounds refer to a parameterized type that cannot be instantiated 148 * for any reason 149 */ 150 public Type[] getLowerBounds() { 151 // lazily initialize bounds if necessary 152 Type[] ts = lowerBounds; 153 if (ts == null) { 154 FieldTypeSignature[] fts = lowerBoundASTs; // get AST 155 if (fts == null) { 156 // race with concurrent initialization 157 ts = lowerBounds; 158 assert ts != null; 159 } else { 160 // allocate result array; note that 161 // keeping ts and bounds separate helps with threads 162 ts = new Type[fts.length]; 163 // iterate over bound trees, reifying each in turn 164 for ( int j = 0; j < fts.length; j++) { 165 Reifier r = getReifier(); 166 fts[j].accept(r); 167 ts[j] = r.getResult(); 168 } 169 // cache result 170 lowerBounds = ts; 171 // throw away lower bound ASTs 172 lowerBoundASTs = null; 173 } 174 } 175 return ts.clone(); // return cached bounds 176 } 177 178 public String toString() { 179 Type[] lowerBounds = getLowerBounds(); 180 Type[] bounds = lowerBounds; 181 StringBuilder sb = new StringBuilder(); 182 183 if (lowerBounds.length > 0) 184 sb.append("? super "); 185 else { 186 Type[] upperBounds = getUpperBounds(); 187 if (upperBounds.length > 0 && !upperBounds[0].equals(Object.class) ) { 188 bounds = upperBounds; 189 sb.append("? extends "); 190 } else 191 return "?"; 192 } 193 194 assert bounds.length > 0; 195 196 boolean first = true; 197 for(Type bound: bounds) { 198 if (!first) 199 sb.append(" & "); 200 201 first = false; 202 sb.append(bound.getTypeName()); 203 } 204 return sb.toString(); 205 } 206 207 @Override 208 public boolean equals(Object o) { 209 if (o instanceof WildcardType) { 210 WildcardType that = (WildcardType) o; 211 return 212 Arrays.equals(this.getLowerBounds(), 213 that.getLowerBounds()) && 214 Arrays.equals(this.getUpperBounds(), 215 that.getUpperBounds()); 216 } else 217 return false; 218 } 219 220 @Override 221 public int hashCode() { 222 Type [] lowerBounds = getLowerBounds(); 223 Type [] upperBounds = getUpperBounds(); 224 225 return Arrays.hashCode(lowerBounds) ^ Arrays.hashCode(upperBounds); 226 } 227 }