-
CSR
-
Resolution: Approved
-
P4
-
source
-
minimal
-
There are likely zero implementations of the interface outside of the platform. Notably Guava seem to lack one. With a default method the compatibility is minimal.
-
Java API
-
SE
Summary
Add getAnnotatedOwnerType()
to AnnotatedType
along with type-specific overrides in subtypes.
Problem
When adding the interface java.lang.reflect.AnnotatedParameterizedType to be the counterpart with annotations to the interface j.l.r.ParameterizedType the method getAnnotatedOwner() was forgotten. The result is that for non-top-level classes, there is no way to get the potentially annotated owner type with annotations intact.
Further investigation showed that there also is no way to navigate to the enclosing type in an AnnotatedType representing a non-parameterized type e.g. @Foo Outer. @Bar Inner . These types are not instances of AnnotatedParameterizedType but plain AnnotatedTypes.
AnnotatedType is an interface. It is unfortunately not possible to add a default method that fully computes the correct result, it depends on the concrete implementation of the interface.
Solution
Add java.lang.reflect.AnnotatedType.getAnnotatedOwner() with a default implementation returning null. For clarity, subinterfaces override the new method to restate the particular requirements and to reduce the number of exceptions thrown.
This method should return null for top-level types and instances of AnnotatedType that can not be nested, like AnnotatedWildcardType, AnnotatedArrayType, and AnnotatedTypeVariable.
Specification
--- old/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java 2015-12-13 21:16:22.000000000 +0100
+++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java 2015-12-13 21:16:22.000000000 +0100
@@ -36,9 +36,40 @@
public interface AnnotatedType extends AnnotatedElement {
/**
+ * Returns the potentially annotated type that this type is a member of, if
+ * this type represents a nested type. For example, if this type is
+ * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+ *
+ * <p>Returns {@code null} if this {@code AnnotatedType} represents a
+ * top-level type, or a local or anonymous class, or a primitive type, or
+ * void.
+ *
+ * <p>Returns {@code null} if this {@code AnnotatedType} is an instance of
+ * {@code AnnotatedArrayType}, {@code AnnotatedTypeVariable}, or
+ * {@code AnnotatedWildcardType}.
+ *
+ * @implSpec
+ * This default implementation returns {@code null} and performs no other
+ * action.
+ *
+ * @return an {@code AnnotatedType} object representing the potentially
+ * annotated type that this type is a member of, or {@code null}
+ * @throws TypeNotPresentException if the owner type
+ * refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if the owner type
+ * refers to a parameterized type that cannot be instantiated
+ * for any reason
+ *
+ * @since 1.9
+ */
+ default AnnotatedType getAnnotatedOwnerType() {
+ return null;
+ }
+
+ /**
* Returns the underlying type that this annotated type represents.
*
* @return the type this annotated type represents
*/
public Type getType();
-}
+}
--- old/src/java.base/share/classes/java/lang/reflect/AnnotatedArrayType.java 2015-12-13 21:16:21.000000000 +0100
+++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedArrayType.java 2015-12-13 21:16:21.000000000 +0100
@@ -42,4 +42,19 @@
* @see GenericArrayType#getGenericComponentType()
*/
AnnotatedType getAnnotatedGenericComponentType();
+
+ /**
+ * Returns the potentially annotated type that this type is a member of, if
+ * this type represents a nested type. For example, if this type is
+ * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+ *
+ * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
+ * of {@code AnnotatedArrayType}.
+ *
+ * @return {@code null}
+ *
+ * @since 1.9
+ */
+ @Override
+ AnnotatedType getAnnotatedOwnerType();
}
--- old/src/java.base/share/classes/java/lang/reflect/AnnotatedParameterizedType.java 2015-12-13 21:16:21.000000000 +0100
+++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedParameterizedType.java 2015-12-13 21:16:21.000000000 +0100
@@ -41,4 +41,26 @@
* @see ParameterizedType#getActualTypeArguments()
*/
AnnotatedType[] getAnnotatedActualTypeArguments();
+
+ /**
+ * Returns the potentially annotated type that this type is a member of, if
+ * this type represents a nested type. For example, if this type is
+ * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+ *
+ * <p>Returns {@code null} if this {@code AnnotatedType} represents a
+ * top-level type, or a local or anonymous class, or a primitive type, or
+ * void.
+ *
+ * @return an {@code AnnotatedType} object representing the potentially
+ * annotated type that this type is a member of, or {@code null}
+ * @throws TypeNotPresentException if the owner type
+ * refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if the owner type
+ * refers to a parameterized type that cannot be instantiated
+ * for any reason
+ *
+ * @since 1.9
+ */
+ @Override
+ AnnotatedType getAnnotatedOwnerType();
}
--- old/src/java.base/share/classes/java/lang/reflect/AnnotatedTypeVariable.java 2015-12-13 21:16:23.000000000 +0100
+++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedTypeVariable.java 2015-12-13 21:16:23.000000000 +0100
@@ -43,4 +43,19 @@
* @see TypeVariable#getBounds()
*/
AnnotatedType[] getAnnotatedBounds();
+
+ /**
+ * Returns the potentially annotated type that this type is a member of, if
+ * this type represents a nested type. For example, if this type is
+ * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+ *
+ * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
+ * of {@code AnnotatedTypeVariable}.
+ *
+ * @return {@code null}
+ *
+ * @since 1.9
+ */
+ @Override
+ AnnotatedType getAnnotatedOwnerType();
}
--- old/src/java.base/share/classes/java/lang/reflect/AnnotatedWildcardType.java 2015-12-13 21:16:23.000000000 +0100
+++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedWildcardType.java 2015-12-13 21:16:23.000000000 +0100
@@ -54,4 +54,19 @@
* @see WildcardType#getUpperBounds()
*/
AnnotatedType[] getAnnotatedUpperBounds();
+
+ /**
+ * Returns the potentially annotated type that this type is a member of, if
+ * this type represents a nested type. For example, if this type is
+ * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+ *
+ * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
+ * of {@code AnnotatedWildcardType}.
+ *
+ * @return {@code null}
+ *
+ * @since 1.9
+ */
+ @Override
+ AnnotatedType getAnnotatedOwnerType();
}
- csr for
-
JDK-8057804 AnnotatedType interfaces provide no way to get annotations on owner type
-
- Resolved
-