1 /* 2 * Copyright (c) 2003, 2013, 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 43 /* 44 * We are required to evaluate the bounds lazily, so we store them as ASTs 45 * until we are first asked for them. This also neatly solves the problem 46 * with F-bounds - you can't reify them before the formal is defined. 47 */ 48 49 /** The upper bounds. Lazily converted from FieldTypeSignature[] to Type[]. */ 50 private volatile Object[] upperBounds; 51 52 /** The lower bounds. Lazily converted from FieldTypeSignature[] to Type[]. */ 53 private volatile Object[] lowerBounds; 54 55 // constructor is private to enforce access through static factory 56 private WildcardTypeImpl(FieldTypeSignature[] ubs, 57 FieldTypeSignature[] lbs, 58 GenericsFactory f) { 59 super(f); 60 upperBounds = ubs; 61 lowerBounds = lbs; 62 } 63 64 /** 65 * Factory method. 66 * @param ubs - an array of ASTs representing the upper bounds for the type 67 * variable to be created 68 * @param lbs - an array of ASTs representing the lower bounds for the type 69 * variable to be created 70 * @param f - a factory that can be used to manufacture reflective 71 * objects that represent the bounds of this wildcard type 72 * @return a wild card type with the requested bounds and factory 73 */ 74 public static WildcardTypeImpl make(FieldTypeSignature[] ubs, 75 FieldTypeSignature[] lbs, 76 GenericsFactory f) { 77 return new WildcardTypeImpl(ubs, lbs, f); 78 } 79 80 /** 81 * Returns an array of <tt>Type</tt> objects representing the upper 82 * bound(s) of this type variable. Note that if no upper bound is 83 * explicitly declared, the upper bound is <tt>Object</tt>. 84 * 85 * <p>For each upper bound B : 86 * <ul> 87 * <li>if B is a parameterized type or a type variable, it is created, 88 * (see {@link #ParameterizedType} for the details of the creation 89 * process for parameterized types). 90 * <li>Otherwise, B is resolved. 91 * </ul> 92 * 93 * @return an array of Types representing the upper bound(s) of this 94 * type variable 95 * @throws <tt>TypeNotPresentException</tt> if any of the 96 * bounds refers to a non-existent type declaration 97 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 98 * bounds refer to a parameterized type that cannot be instantiated 99 * for any reason 100 */ 101 public Type[] getUpperBounds() { 102 Object[] value = upperBounds; 103 if (value instanceof FieldTypeSignature[]) { 104 value = reifyBounds((FieldTypeSignature[])value); 105 upperBounds = value; 106 } 107 return (Type[])value.clone(); 108 } 109 110 /** 111 * Returns an array of <tt>Type</tt> objects representing the 112 * lower bound(s) of this type variable. Note that if no lower bound is 113 * explicitly declared, the lower bound is the type of <tt>null</tt>. 114 * In this case, a zero length array is returned. 115 * 116 * <p>For each lower bound B : 117 * <ul> 118 * <li>if B is a parameterized type or a type variable, it is created, 119 * (see {@link #ParameterizedType} for the details of the creation 120 * process for parameterized types). 121 * <li>Otherwise, B is resolved. 122 * </ul> 123 * 124 * @return an array of Types representing the lower bound(s) of this 125 * type variable 126 * @throws <tt>TypeNotPresentException</tt> if any of the 127 * bounds refers to a non-existent type declaration 128 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 129 * bounds refer to a parameterized type that cannot be instantiated 130 * for any reason 131 */ 132 public Type[] getLowerBounds() { 133 Object[] value = lowerBounds; 134 if (value instanceof FieldTypeSignature[]) { 135 value = reifyBounds((FieldTypeSignature[])value); 136 lowerBounds = value; 137 } 138 return (Type[])value.clone(); 139 } 140 141 public String toString() { 142 Type[] lowerBounds = getLowerBounds(); 143 Type[] bounds = lowerBounds; 144 StringBuilder sb = new StringBuilder(); 145 146 if (lowerBounds.length > 0) 147 sb.append("? super "); 148 else { 149 Type[] upperBounds = getUpperBounds(); 150 if (upperBounds.length > 0 && !upperBounds[0].equals(Object.class) ) { 151 bounds = upperBounds; 152 sb.append("? extends "); 153 } else 154 return "?"; 155 } 156 157 assert bounds.length > 0; 158 159 boolean first = true; 160 for(Type bound: bounds) { 161 if (!first) 162 sb.append(" & "); 163 164 first = false; 165 sb.append(bound.getTypeName()); 166 } 167 return sb.toString(); 168 } 169 170 @Override 171 public boolean equals(Object o) { 172 if (o instanceof WildcardType) { 173 WildcardType that = (WildcardType) o; 174 return 175 Arrays.equals(this.getLowerBounds(), 176 that.getLowerBounds()) && 177 Arrays.equals(this.getUpperBounds(), 178 that.getUpperBounds()); 179 } else 180 return false; 181 } 182 183 @Override 184 public int hashCode() { 185 Type [] lowerBounds = getLowerBounds(); 186 Type [] upperBounds = getUpperBounds(); 187 188 return Arrays.hashCode(lowerBounds) ^ Arrays.hashCode(upperBounds); 189 } 190 }