< prev index next >
src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java
Print this page
@@ -29,10 +29,12 @@
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
import static sun.reflect.annotation.TypeAnnotation.*;
public final class AnnotatedTypeFactory {
/**
@@ -200,10 +202,69 @@
return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
}
+ @Override
+ public String toString() {
+ // Reusable toString implementation, but needs to be
+ // specialized for quirks of arrays.
+ return annotationsToString(getAnnotations(), false) + type.toString();
+ }
+
+ protected String annotationsToString(Annotation[] annotations, boolean leadingSpace) {
+ StringJoiner sj = new StringJoiner(" ");
+ if (annotations != null && annotations.length > 0) {
+ if (leadingSpace) {
+ sj.add(""); // Add a space
+ }
+
+ for (Annotation annotation : annotations) {
+ sj.add(annotation.toString());
+ }
+
+ if (!leadingSpace) {
+ sj.add("");
+ }
+ }
+ return sj.toString();
+ }
+
+ protected boolean equalsTypeAndAnnotations(AnnotatedType that) {
+ return getType().equals(that.getType()) &&
+ // Treat ordering of annotations as significant
+ Arrays.equals(getAnnotations(), that.getAnnotations()) &&
+ Objects.equals(getAnnotatedOwnerType(), that.getAnnotatedOwnerType());
+ }
+
+ int baseHashCode() {
+ return type.hashCode() ^
+ // Acceptable to use Objects.hash rather than
+ // Arrays.deepHashCode since the elements of the array
+ // are not themselves arrays.
+ Objects.hash((Object[])getAnnotations());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof AnnotatedType &&
+ !(o instanceof AnnotatedArrayType) &&
+ !(o instanceof AnnotatedTypeVariable) &&
+ !(o instanceof AnnotatedParameterizedType) &&
+ !(o instanceof AnnotatedWildcardType)) {
+ AnnotatedType that = (AnnotatedType) o;
+ return equalsTypeAndAnnotations(that);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode();
+ }
+
// Implementation details
final LocationInfo getLocation() {
return location;
}
final TypeAnnotation[] getTypeAnnotations() {
@@ -242,10 +303,56 @@
Class<?> c = (Class)t;
return c.getComponentType();
}
return ((GenericArrayType)t).getGenericComponentType();
}
+
+ @Override
+ public String toString() {
+ // To annotate the full type of an array, the annotations
+ // are placed between the type and the brackets. For
+ // example, to annotate an array of Strings, the syntax used is
+ //
+ // String @TypeAnnotation []
+ //
+ // and *not*
+ //
+ // @TypeAnnotation String[].
+ //
+ // The toString output should strive to be reusable in
+ // source code. Therefore, the general logic of putting
+ // the annotations before a textual representation of the
+ // type need to be overridden for arrays.
+ StringBuilder sb = new StringBuilder();
+
+ AnnotatedType componentType = this;
+ while (componentType instanceof AnnotatedArrayType) {
+ AnnotatedArrayType annotatedArrayType = (AnnotatedArrayType) componentType;
+ sb.append(annotationsToString(annotatedArrayType.getAnnotations(), true) + "[]");
+ componentType = annotatedArrayType.getAnnotatedGenericComponentType();
+ }
+
+ sb.insert(0, componentType.toString());
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof AnnotatedArrayType) {
+ AnnotatedArrayType that = (AnnotatedArrayType) o;
+ return equalsTypeAndAnnotations(that) &&
+ Objects.equals(getAnnotatedGenericComponentType(),
+ that.getAnnotatedGenericComponentType());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode() ^ getAnnotatedGenericComponentType().hashCode();
+ }
}
private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
@@ -264,10 +371,27 @@
}
private TypeVariable<?> getTypeVariable() {
return (TypeVariable)getType();
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof AnnotatedTypeVariable) {
+ AnnotatedTypeVariable that = (AnnotatedTypeVariable) o;
+ return equalsTypeAndAnnotations(that) &&
+ Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode() ^
+ Objects.hash((Object[])getAnnotatedBounds());
+ }
}
private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
implements AnnotatedParameterizedType {
AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
@@ -314,10 +438,27 @@
}
private ParameterizedType getParameterizedType() {
return (ParameterizedType)getType();
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof AnnotatedParameterizedType) {
+ AnnotatedParameterizedType that = (AnnotatedParameterizedType) o;
+ return equalsTypeAndAnnotations(that) &&
+ Arrays.equals(getAnnotatedActualTypeArguments(), that.getAnnotatedActualTypeArguments());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode() ^
+ Objects.hash((Object[])getAnnotatedActualTypeArguments());
+ }
}
private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
private final boolean hasUpperBounds;
AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
@@ -376,7 +517,28 @@
}
private boolean hasUpperBounds() {
return hasUpperBounds;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof AnnotatedWildcardType) {
+ AnnotatedWildcardType that = (AnnotatedWildcardType) o;
+ return equalsTypeAndAnnotations(that) &&
+ // Treats ordering as significant
+ Arrays.equals(getAnnotatedLowerBounds(), that.getAnnotatedLowerBounds()) &&
+ // Treats ordering as significant
+ Arrays.equals(getAnnotatedUpperBounds(), that.getAnnotatedUpperBounds());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode() ^
+ Objects.hash((Object[])getAnnotatedLowerBounds()) ^
+ Objects.hash((Object[])getAnnotatedUpperBounds());
+ }
}
}
< prev index next >