< prev index next >

src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java

Print this page


   1 /*
   2  * Copyright (c) 2013, 2015, 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.annotation;
  27 
  28 import java.lang.annotation.*;
  29 import java.lang.reflect.*;
  30 import java.util.ArrayList;
  31 import java.util.Arrays;
  32 import java.util.List;
  33 import java.util.Map;


  34 
  35 import static sun.reflect.annotation.TypeAnnotation.*;
  36 
  37 public final class AnnotatedTypeFactory {
  38     /**
  39      * Create an AnnotatedType.
  40      *
  41      * @param type the type this AnnotatedType corresponds to
  42      * @param currentLoc the location this AnnotatedType corresponds to
  43      * @param actualTypeAnnos the type annotations this AnnotatedType has
  44      * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget
  45      *                          as the AnnotatedType being built
  46      * @param decl the declaration having the type use this AnnotatedType
  47      *                          corresponds to
  48      */
  49     public static AnnotatedType buildAnnotatedType(Type type,
  50             LocationInfo currentLoc,
  51             TypeAnnotation[] actualTypeAnnos,
  52             TypeAnnotation[] allOnSameTarget,
  53             AnnotatedElement decl) {


 185 
 186             Class<?> inner = (Class<?>)type;
 187             Class<?> owner = inner.getDeclaringClass();
 188             if (owner == null) // top-level, local or anonymous
 189                 return null;
 190             if (inner.isPrimitive() || inner == Void.TYPE)
 191                 return null;
 192 
 193             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 194             TypeAnnotation[]all = getTypeAnnotations();
 195             List<TypeAnnotation> l = new ArrayList<>(all.length);
 196 
 197             for (TypeAnnotation t : all)
 198                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 199                     l.add(t);
 200 
 201             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 202 
 203         }
 204 






























































 205         // Implementation details
 206         final LocationInfo getLocation() {
 207             return location;
 208         }
 209         final TypeAnnotation[] getTypeAnnotations() {
 210             return allOnSameTargetTypeAnnotations;
 211         }
 212         final AnnotatedElement getDecl() {
 213             return decl;
 214         }
 215     }
 216 
 217     private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType {
 218         AnnotatedArrayTypeImpl(Type type, LocationInfo location,
 219                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 220                 AnnotatedElement decl) {
 221             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 222         }
 223 
 224         @Override


 227             return AnnotatedTypeFactory.buildAnnotatedType(t,
 228                     nestingForType(t, getLocation().pushArray()),
 229                     getTypeAnnotations(),
 230                     getTypeAnnotations(),
 231                     getDecl());
 232         }
 233 
 234         @Override
 235         public AnnotatedType getAnnotatedOwnerType() {
 236             return null;
 237         }
 238 
 239         private Type getComponentType() {
 240             Type t = getType();
 241             if (t instanceof Class) {
 242                 Class<?> c = (Class)t;
 243                 return c.getComponentType();
 244             }
 245             return ((GenericArrayType)t).getGenericComponentType();
 246         }














































 247     }
 248 
 249     private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
 250         AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
 251                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 252                 AnnotatedElement decl) {
 253             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 254         }
 255 
 256         @Override
 257         public AnnotatedType[] getAnnotatedBounds() {
 258             return getTypeVariable().getAnnotatedBounds();
 259         }
 260 
 261         @Override
 262         public AnnotatedType getAnnotatedOwnerType() {
 263             return null;
 264         }
 265 
 266         private TypeVariable<?> getTypeVariable() {
 267             return (TypeVariable)getType();
 268         }

















 269     }
 270 
 271     private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
 272             implements AnnotatedParameterizedType {
 273         AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
 274                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 275                 AnnotatedElement decl) {
 276             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 277         }
 278 
 279         @Override
 280         public AnnotatedType[] getAnnotatedActualTypeArguments() {
 281             Type[] arguments = getParameterizedType().getActualTypeArguments();
 282             AnnotatedType[] res = new AnnotatedType[arguments.length];
 283             Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
 284             int initialCapacity = getTypeAnnotations().length;
 285             for (int i = 0; i < res.length; i++) {
 286                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 287                 LocationInfo newLoc = nestingForType(arguments[i], getLocation().pushTypeArg((byte)i));
 288                 for (TypeAnnotation t : getTypeAnnotations())


 299 
 300         @Override
 301         public AnnotatedType getAnnotatedOwnerType() {
 302             Type owner = getParameterizedType().getOwnerType();
 303             if (owner == null)
 304                 return null;
 305             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 306             TypeAnnotation[]all = getTypeAnnotations();
 307             List<TypeAnnotation> l = new ArrayList<>(all.length);
 308 
 309             for (TypeAnnotation t : all)
 310                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 311                     l.add(t);
 312 
 313             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 314         }
 315 
 316         private ParameterizedType getParameterizedType() {
 317             return (ParameterizedType)getType();
 318         }

















 319     }
 320 
 321     private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
 322         private final boolean hasUpperBounds;
 323         AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
 324                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 325                 AnnotatedElement decl) {
 326             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 327             hasUpperBounds = (type.getLowerBounds().length == 0);
 328         }
 329 
 330         @Override
 331         public AnnotatedType[] getAnnotatedUpperBounds() {
 332             if (!hasUpperBounds()) {
 333                 return new AnnotatedType[] { buildAnnotatedType(Object.class,
 334                         LocationInfo.BASE_LOCATION,
 335                         EMPTY_TYPE_ANNOTATION_ARRAY,
 336                         EMPTY_TYPE_ANNOTATION_ARRAY,
 337                         null)
 338                 };


 360                 LocationInfo newLoc = nestingForType(bounds[i], getLocation().pushWildcard());
 361                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 362                 for (TypeAnnotation t : getTypeAnnotations())
 363                     if (t.getLocationInfo().isSameLocationInfo(newLoc))
 364                         l.add(t);
 365                 res[i] = buildAnnotatedType(bounds[i],
 366                         newLoc,
 367                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
 368                         getTypeAnnotations(),
 369                         getDecl());
 370             }
 371             return res;
 372         }
 373 
 374         private WildcardType getWildcardType() {
 375             return (WildcardType)getType();
 376         }
 377 
 378         private boolean hasUpperBounds() {
 379             return hasUpperBounds;





















 380         }
 381     }
 382 }
   1 /*
   2  * Copyright (c) 2013, 2018, 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.annotation;
  27 
  28 import java.lang.annotation.*;
  29 import java.lang.reflect.*;
  30 import java.util.ArrayList;
  31 import java.util.Arrays;
  32 import java.util.List;
  33 import java.util.Map;
  34 import java.util.Objects;
  35 import java.util.StringJoiner;
  36 
  37 import static sun.reflect.annotation.TypeAnnotation.*;
  38 
  39 public final class AnnotatedTypeFactory {
  40     /**
  41      * Create an AnnotatedType.
  42      *
  43      * @param type the type this AnnotatedType corresponds to
  44      * @param currentLoc the location this AnnotatedType corresponds to
  45      * @param actualTypeAnnos the type annotations this AnnotatedType has
  46      * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget
  47      *                          as the AnnotatedType being built
  48      * @param decl the declaration having the type use this AnnotatedType
  49      *                          corresponds to
  50      */
  51     public static AnnotatedType buildAnnotatedType(Type type,
  52             LocationInfo currentLoc,
  53             TypeAnnotation[] actualTypeAnnos,
  54             TypeAnnotation[] allOnSameTarget,
  55             AnnotatedElement decl) {


 187 
 188             Class<?> inner = (Class<?>)type;
 189             Class<?> owner = inner.getDeclaringClass();
 190             if (owner == null) // top-level, local or anonymous
 191                 return null;
 192             if (inner.isPrimitive() || inner == Void.TYPE)
 193                 return null;
 194 
 195             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 196             TypeAnnotation[]all = getTypeAnnotations();
 197             List<TypeAnnotation> l = new ArrayList<>(all.length);
 198 
 199             for (TypeAnnotation t : all)
 200                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 201                     l.add(t);
 202 
 203             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 204 
 205         }
 206 
 207         @Override // java.lang.Object
 208         public String toString() {
 209             // Reusable toString implementation, but needs to be
 210             // specialized for quirks of arrays.
 211             return annotationsToString(getAnnotations(), false) + type.toString();
 212         }
 213 
 214         protected String annotationsToString(Annotation[] annotations, boolean leadingSpace) {
 215             if (annotations != null && annotations.length > 0) {
 216                 StringJoiner sj = new StringJoiner(" ");
 217                 if (leadingSpace) {
 218                     sj.add(""); // Add a space
 219                 }
 220 
 221                 for (Annotation annotation : annotations) {
 222                     sj.add(annotation.toString());
 223                 }
 224 
 225                 if (!leadingSpace) {
 226                     sj.add("");
 227                 }
 228                 return sj.toString();
 229             } else {
 230                 return "";
 231             }
 232         }
 233 
 234         protected boolean equalsTypeAndAnnotations(AnnotatedType that) {
 235             return getType().equals(that.getType()) &&
 236                 // Treat ordering of annotations as significant
 237                 Arrays.equals(getAnnotations(), that.getAnnotations()) &&
 238                 Objects.equals(getAnnotatedOwnerType(), that.getAnnotatedOwnerType());
 239         }
 240 
 241         int baseHashCode() {
 242             return type.hashCode() ^
 243                 // Acceptable to use Objects.hash rather than
 244                 // Arrays.deepHashCode since the elements of the array
 245                 // are not themselves arrays.
 246                 Objects.hash((Object[])getAnnotations()) ^
 247                 Objects.hash(getAnnotatedOwnerType());
 248         }
 249 
 250         @Override
 251         public boolean equals(Object o) {
 252             if (o instanceof AnnotatedType &&
 253                 !(o instanceof AnnotatedArrayType) &&
 254                 !(o instanceof AnnotatedTypeVariable) &&
 255                 !(o instanceof AnnotatedParameterizedType) &&
 256                 !(o instanceof AnnotatedWildcardType)) {
 257                 AnnotatedType that = (AnnotatedType) o;
 258                 return equalsTypeAndAnnotations(that);
 259             } else {
 260                 return false;
 261             }
 262         }
 263 
 264         @Override
 265         public int hashCode() {
 266             return baseHashCode();
 267         }
 268 
 269         // Implementation details
 270         final LocationInfo getLocation() {
 271             return location;
 272         }
 273         final TypeAnnotation[] getTypeAnnotations() {
 274             return allOnSameTargetTypeAnnotations;
 275         }
 276         final AnnotatedElement getDecl() {
 277             return decl;
 278         }
 279     }
 280 
 281     private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType {
 282         AnnotatedArrayTypeImpl(Type type, LocationInfo location,
 283                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 284                 AnnotatedElement decl) {
 285             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 286         }
 287 
 288         @Override


 291             return AnnotatedTypeFactory.buildAnnotatedType(t,
 292                     nestingForType(t, getLocation().pushArray()),
 293                     getTypeAnnotations(),
 294                     getTypeAnnotations(),
 295                     getDecl());
 296         }
 297 
 298         @Override
 299         public AnnotatedType getAnnotatedOwnerType() {
 300             return null;
 301         }
 302 
 303         private Type getComponentType() {
 304             Type t = getType();
 305             if (t instanceof Class) {
 306                 Class<?> c = (Class)t;
 307                 return c.getComponentType();
 308             }
 309             return ((GenericArrayType)t).getGenericComponentType();
 310         }
 311 
 312         @Override
 313         public String toString() {
 314             // To annotate the full type of an array, the annotations
 315             // are placed between the type and the brackets. For
 316             // example, to annotate an array of Strings, the syntax used is
 317             //
 318             // String @TypeAnnotation []
 319             //
 320             // and *not*
 321             //
 322             // @TypeAnnotation String[].
 323             //
 324             // The toString output should strive to be reusable in
 325             // source code. Therefore, the general logic of putting
 326             // the annotations before a textual representation of the
 327             // type need to be overridden for arrays.
 328             StringBuilder sb = new StringBuilder();
 329 
 330             AnnotatedType componentType = this;
 331             while (componentType instanceof AnnotatedArrayType) {
 332                 AnnotatedArrayType annotatedArrayType = (AnnotatedArrayType) componentType;
 333                 sb.append(annotationsToString(annotatedArrayType.getAnnotations(), true) + "[]");
 334                 componentType = annotatedArrayType.getAnnotatedGenericComponentType();
 335             }
 336 
 337             sb.insert(0, componentType.toString());
 338             return sb.toString();
 339         }
 340 
 341         @Override
 342         public boolean equals(Object o) {
 343             if (o instanceof AnnotatedArrayType) {
 344                 AnnotatedArrayType that = (AnnotatedArrayType) o;
 345                 return equalsTypeAndAnnotations(that) &&
 346                     Objects.equals(getAnnotatedGenericComponentType(),
 347                                    that.getAnnotatedGenericComponentType());
 348             } else {
 349                 return false;
 350             }
 351         }
 352 
 353         @Override
 354         public int hashCode() {
 355             return baseHashCode() ^ getAnnotatedGenericComponentType().hashCode();
 356         }
 357     }
 358 
 359     private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
 360         AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
 361                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 362                 AnnotatedElement decl) {
 363             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 364         }
 365 
 366         @Override
 367         public AnnotatedType[] getAnnotatedBounds() {
 368             return getTypeVariable().getAnnotatedBounds();
 369         }
 370 
 371         @Override
 372         public AnnotatedType getAnnotatedOwnerType() {
 373             return null;
 374         }
 375 
 376         private TypeVariable<?> getTypeVariable() {
 377             return (TypeVariable)getType();
 378         }
 379 
 380         @Override
 381         public boolean equals(Object o) {
 382             if (o instanceof AnnotatedTypeVariable) {
 383                 AnnotatedTypeVariable that = (AnnotatedTypeVariable) o;
 384                 return equalsTypeAndAnnotations(that) &&
 385                     Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds());
 386             } else {
 387                 return false;
 388             }
 389         }
 390 
 391         @Override
 392         public int hashCode() {
 393             return baseHashCode() ^
 394                 Objects.hash((Object[])getAnnotatedBounds());
 395         }
 396     }
 397 
 398     private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
 399             implements AnnotatedParameterizedType {
 400         AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
 401                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 402                 AnnotatedElement decl) {
 403             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 404         }
 405 
 406         @Override
 407         public AnnotatedType[] getAnnotatedActualTypeArguments() {
 408             Type[] arguments = getParameterizedType().getActualTypeArguments();
 409             AnnotatedType[] res = new AnnotatedType[arguments.length];
 410             Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
 411             int initialCapacity = getTypeAnnotations().length;
 412             for (int i = 0; i < res.length; i++) {
 413                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 414                 LocationInfo newLoc = nestingForType(arguments[i], getLocation().pushTypeArg((byte)i));
 415                 for (TypeAnnotation t : getTypeAnnotations())


 426 
 427         @Override
 428         public AnnotatedType getAnnotatedOwnerType() {
 429             Type owner = getParameterizedType().getOwnerType();
 430             if (owner == null)
 431                 return null;
 432             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 433             TypeAnnotation[]all = getTypeAnnotations();
 434             List<TypeAnnotation> l = new ArrayList<>(all.length);
 435 
 436             for (TypeAnnotation t : all)
 437                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 438                     l.add(t);
 439 
 440             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 441         }
 442 
 443         private ParameterizedType getParameterizedType() {
 444             return (ParameterizedType)getType();
 445         }
 446 
 447         @Override
 448         public boolean equals(Object o) {
 449             if (o instanceof AnnotatedParameterizedType) {
 450                 AnnotatedParameterizedType that = (AnnotatedParameterizedType) o;
 451                 return equalsTypeAndAnnotations(that) &&
 452                     Arrays.equals(getAnnotatedActualTypeArguments(), that.getAnnotatedActualTypeArguments());
 453             } else {
 454                 return false;
 455             }
 456         }
 457 
 458         @Override
 459         public int hashCode() {
 460             return baseHashCode() ^
 461                 Objects.hash((Object[])getAnnotatedActualTypeArguments());
 462         }
 463     }
 464 
 465     private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
 466         private final boolean hasUpperBounds;
 467         AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
 468                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 469                 AnnotatedElement decl) {
 470             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 471             hasUpperBounds = (type.getLowerBounds().length == 0);
 472         }
 473 
 474         @Override
 475         public AnnotatedType[] getAnnotatedUpperBounds() {
 476             if (!hasUpperBounds()) {
 477                 return new AnnotatedType[] { buildAnnotatedType(Object.class,
 478                         LocationInfo.BASE_LOCATION,
 479                         EMPTY_TYPE_ANNOTATION_ARRAY,
 480                         EMPTY_TYPE_ANNOTATION_ARRAY,
 481                         null)
 482                 };


 504                 LocationInfo newLoc = nestingForType(bounds[i], getLocation().pushWildcard());
 505                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 506                 for (TypeAnnotation t : getTypeAnnotations())
 507                     if (t.getLocationInfo().isSameLocationInfo(newLoc))
 508                         l.add(t);
 509                 res[i] = buildAnnotatedType(bounds[i],
 510                         newLoc,
 511                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
 512                         getTypeAnnotations(),
 513                         getDecl());
 514             }
 515             return res;
 516         }
 517 
 518         private WildcardType getWildcardType() {
 519             return (WildcardType)getType();
 520         }
 521 
 522         private boolean hasUpperBounds() {
 523             return hasUpperBounds;
 524         }
 525 
 526         @Override
 527         public boolean equals(Object o) {
 528             if (o instanceof AnnotatedWildcardType) {
 529                 AnnotatedWildcardType that = (AnnotatedWildcardType) o;
 530                 return equalsTypeAndAnnotations(that) &&
 531                     // Treats ordering as significant
 532                     Arrays.equals(getAnnotatedLowerBounds(), that.getAnnotatedLowerBounds()) &&
 533                     // Treats ordering as significant
 534                     Arrays.equals(getAnnotatedUpperBounds(), that.getAnnotatedUpperBounds());
 535             } else {
 536                 return false;
 537             }
 538         }
 539 
 540         @Override
 541         public int hashCode() {
 542             return baseHashCode() ^
 543                 Objects.hash((Object[])getAnnotatedLowerBounds()) ^
 544                 Objects.hash((Object[])getAnnotatedUpperBounds());
 545         }
 546     }
 547 }
< prev index next >