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