From 455d2e7cea03424717faf3826221213f30eca26d Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 9 Apr 2020 14:16:17 -0700 Subject: [PATCH] 8225540: In core reflection note whether returned annotations are declaration or type annotations Reviewed-by: alanb, prappo --- .../share/classes/java/lang/Class.java | 27 ++++++++++++ .../share/classes/java/lang/Module.java | 9 ++++ .../share/classes/java/lang/Package.java | 21 +++++++++ .../java/lang/reflect/AccessibleObject.java | 36 ++++++++++++++- .../java/lang/reflect/AnnotatedElement.java | 44 +++++++++++++------ .../java/lang/reflect/AnnotatedType.java | 34 +++++++++++++- .../java/lang/reflect/Constructor.java | 5 ++- .../classes/java/lang/reflect/Executable.java | 8 +++- .../classes/java/lang/reflect/Field.java | 7 ++- .../classes/java/lang/reflect/Method.java | 4 +- .../classes/java/lang/reflect/Modifier.java | 7 +-- .../classes/java/lang/reflect/Parameter.java | 24 ++++++++++ .../java/lang/reflect/RecordComponent.java | 7 +++ 13 files changed, 209 insertions(+), 24 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 57c8daf6d1a..7dfe6122eda 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -3779,9 +3779,14 @@ public Class asSubclass(Class clazz) { } /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override @SuppressWarnings("unchecked") public A getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); @@ -3800,6 +3805,10 @@ public boolean isAnnotationPresent(Class annotationClass) } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -3814,13 +3823,22 @@ public A[] getAnnotationsByType(Class annotationClass) } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getAnnotations() { return AnnotationParser.toArray(annotationData().annotations); } /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -3833,6 +3851,10 @@ public A getDeclaredAnnotation(Class annotationClass) } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -3845,8 +3867,13 @@ public A[] getDeclaredAnnotationsByType(Class annotati } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(annotationData().declaredAnnotations); } diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java index 955c0b4babb..70e365ee098 100644 --- a/src/java.base/share/classes/java/lang/Module.java +++ b/src/java.base/share/classes/java/lang/Module.java @@ -1381,6 +1381,9 @@ private static Module findModule(String target, /** * {@inheritDoc} * This method returns {@code null} when invoked on an unnamed module. + * + *

Note that any annotation returned by this method is a + * declaration annotation. */ @Override public T getAnnotation(Class annotationClass) { @@ -1390,6 +1393,9 @@ public T getAnnotation(Class annotationClass) { /** * {@inheritDoc} * This method returns an empty array when invoked on an unnamed module. + * + *

Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getAnnotations() { @@ -1399,6 +1405,9 @@ public Annotation[] getAnnotations() { /** * {@inheritDoc} * This method returns an empty array when invoked on an unnamed module. + * + *

Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getDeclaredAnnotations() { diff --git a/src/java.base/share/classes/java/lang/Package.java b/src/java.base/share/classes/java/lang/Package.java index f6ec1f51022..334d0b4b791 100644 --- a/src/java.base/share/classes/java/lang/Package.java +++ b/src/java.base/share/classes/java/lang/Package.java @@ -434,9 +434,14 @@ class PackageInfoProxy {} } /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public A getAnnotation(Class annotationClass) { return getPackageInfo().getAnnotation(annotationClass); } @@ -452,6 +457,10 @@ public boolean isAnnotationPresent(Class annotationClass) } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -461,13 +470,21 @@ public A[] getAnnotationsByType(Class annotationClass } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. * @since 1.5 */ + @Override public Annotation[] getAnnotations() { return getPackageInfo().getAnnotations(); } /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -486,8 +503,12 @@ public A[] getDeclaredAnnotationsByType(Class annotati } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return getPackageInfo().getDeclaredAnnotations(); } diff --git a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java index 92386bacd65..139974ac9a2 100644 --- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java +++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -509,15 +509,22 @@ protected AccessibleObject() {} new ReflectionFactory.GetReflectionFactoryAction()); /** + * {@inheritDoc} + * + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public T getAnnotation(Class annotationClass) { throw new AssertionError("All subclasses should override this method"); } /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ @@ -527,6 +534,11 @@ public boolean isAnnotationPresent(Class annotationClass) } /** + * {@inheritDoc} + * + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -536,13 +548,24 @@ public T[] getAnnotationsByType(Class annotationClass) } /** + * {@inheritDoc} + * + *

Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getAnnotations() { return getDeclaredAnnotations(); } /** + * {@inheritDoc} + * + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -555,6 +578,11 @@ public T getDeclaredAnnotation(Class annotationClass) } /** + * {@inheritDoc} + * + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -567,8 +595,14 @@ public T[] getDeclaredAnnotationsByType(Class annotati } /** + * {@inheritDoc} + * + *

Note that any annotations returned by this method are + * declaration annotations. + * * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { throw new AssertionError("All subclasses should override this method"); } diff --git a/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java b/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java index 33613e7d378..a4bb8a089ce 100644 --- a/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java +++ b/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java @@ -38,20 +38,38 @@ import sun.reflect.annotation.AnnotationType; /** - * Represents an annotated element of the program currently running in this - * VM. This interface allows annotations to be read reflectively. All + * Represents an annotated construct of the program currently running + * in this VM. + * + * A construct is either an element or a type. Annotations on an + * element are on a declaration, whereas annotations on a + * type are on a specific use of a type name. + * + * As defined by The Java™ Language Specification + * section {@jls 9.7.4}, an annotation on an element is a + * declaration annotation and an annotation on a type is a + * type annotation. + * + * Note that any annotations returned by methods on the {@link + * AnnotatedType AnnotatedType} interface and its subinterfaces are + * type annotations as the entity being potentially annotated is a + * type. Annotations returned by methods outside of the {@code + * AnnotatedType} hierarchy are declaration annotations. + * + *

This interface allows annotations to be read reflectively. All * annotations returned by methods in this interface are immutable and - * serializable. The arrays returned by methods of this interface may be modified - * by callers without affecting the arrays returned to other callers. + * serializable. The arrays returned by methods of this interface may + * be modified by callers without affecting the arrays returned to + * other callers. * *

The {@link #getAnnotationsByType(Class)} and {@link * #getDeclaredAnnotationsByType(Class)} methods support multiple * annotations of the same type on an element. If the argument to - * either method is a repeatable annotation type (JLS 9.6), then the - * method will "look through" a container annotation (JLS 9.7), if - * present, and return any annotations inside the container. Container - * annotations may be generated at compile-time to wrap multiple - * annotations of the argument type. + * either method is a repeatable annotation type (JLS {@jls 9.6}), + * then the method will "look through" a container annotation (JLS + * {@jls 9.7}), if present, and return any annotations inside the + * container. Container annotations may be generated at compile-time + * to wrap multiple annotations of the argument type. * *

The terms directly present, indirectly present, * present, and associated are used throughout this @@ -260,8 +278,8 @@ public interface AnnotatedElement { *

The truth value returned by this method is equivalent to: * {@code getAnnotation(annotationClass) != null} * - *

The body of the default method is specified to be the code - * above. + * @implSpec The default implementation returns {@code + * getAnnotation(annotationClass) != null}. * * @param annotationClass the Class object corresponding to the * annotation type @@ -310,7 +328,7 @@ default boolean isAnnotationPresent(Class annotationClass) * * The difference between this method and {@link #getAnnotation(Class)} * is that this method detects if its argument is a repeatable - * annotation type (JLS 9.6), and if so, attempts to find one or + * annotation type (JLS {@jls 9.6}), and if so, attempts to find one or * more annotations of that type by "looking through" a container * annotation. * @@ -406,7 +424,7 @@ default T getDeclaredAnnotation(Class annotationClass) * * The difference between this method and {@link * #getDeclaredAnnotation(Class)} is that this method detects if its - * argument is a repeatable annotation type (JLS 9.6), and if so, + * argument is a repeatable annotation type (JLS {@jls 9.6}), and if so, * attempts to find one or more annotations of that type by "looking * through" a container annotation if one is present. * diff --git a/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java b/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java index 79a8cd15fdd..a22e5c26336 100644 --- a/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java +++ b/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,18 @@ package java.lang.reflect; +import java.lang.annotation.Annotation; + /** * {@code AnnotatedType} represents the potentially annotated use of a type in * the program currently running in this VM. The use may be of any type in the * Java programming language, including an array type, a parameterized type, a * type variable, or a wildcard type. * + * Note that any annotations returned by methods on this interface are + * type annotations (JLS {@jls 9.7.4}) as the entity being + * potentially annotated is a type. + * * @since 1.8 */ public interface AnnotatedType extends AnnotatedElement { @@ -72,4 +78,30 @@ default AnnotatedType getAnnotatedOwnerType() { * @return the type this annotated type represents */ public Type getType(); + + /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a type + * annotation. + * + * @throws NullPointerException {@inheritDoc} + */ + @Override + T getAnnotation(Class annotationClass); + + /** + * {@inheritDoc} + *

Note that any annotations returned by this method are type + * annotations. + */ + @Override + Annotation[] getAnnotations(); + + /** + * {@inheritDoc} + *

Note that any annotations returned by this method are type + * annotations. + */ + @Override + Annotation[] getDeclaredAnnotations(); } diff --git a/src/java.base/share/classes/java/lang/reflect/Constructor.java b/src/java.base/share/classes/java/lang/reflect/Constructor.java index f1d2cf1485f..a1dafe9935e 100644 --- a/src/java.base/share/classes/java/lang/reflect/Constructor.java +++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -576,9 +576,11 @@ byte[] getRawParameterAnnotations() { /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public T getAnnotation(Class annotationClass) { return super.getAnnotation(annotationClass); } @@ -587,6 +589,7 @@ public T getAnnotation(Class annotationClass) { * {@inheritDoc} * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return super.getDeclaredAnnotations(); } diff --git a/src/java.base/share/classes/java/lang/reflect/Executable.java b/src/java.base/share/classes/java/lang/reflect/Executable.java index 06c058c05c0..67af84c166d 100644 --- a/src/java.base/share/classes/java/lang/reflect/Executable.java +++ b/src/java.base/share/classes/java/lang/reflect/Executable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -544,6 +544,9 @@ public boolean isSynthetic() { * ("synthetic") to the parameter list for a method. See {@link * java.lang.reflect.Parameter} for more information. * + *

Note that any annotations returned by this method are + * declaration annotations. + * * @see java.lang.reflect.Parameter * @see java.lang.reflect.Parameter#getAnnotations * @return an array of arrays that represent the annotations on @@ -577,6 +580,7 @@ Annotation[][] sharedGetParameterAnnotations(Class[] parameterTypes, * {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + @Override public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); return annotationClass.cast(declaredAnnotations().get(annotationClass)); @@ -584,6 +588,7 @@ public T getAnnotation(Class annotationClass) { /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} */ @Override @@ -596,6 +601,7 @@ public T[] getAnnotationsByType(Class annotationClass) /** * {@inheritDoc} */ + @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(declaredAnnotations()); } diff --git a/src/java.base/share/classes/java/lang/reflect/Field.java b/src/java.base/share/classes/java/lang/reflect/Field.java index 2e7ab067fa5..e1435c865c4 100644 --- a/src/java.base/share/classes/java/lang/reflect/Field.java +++ b/src/java.base/share/classes/java/lang/reflect/Field.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1132,9 +1132,12 @@ Field getRoot() { } /** + * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); return annotationClass.cast(declaredAnnotations().get(annotationClass)); @@ -1142,6 +1145,7 @@ public T getAnnotation(Class annotationClass) { /** * {@inheritDoc} + * * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @@ -1155,6 +1159,7 @@ public T[] getAnnotationsByType(Class annotationClass) /** * {@inheritDoc} */ + @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(declaredAnnotations()); } diff --git a/src/java.base/share/classes/java/lang/reflect/Method.java b/src/java.base/share/classes/java/lang/reflect/Method.java index 84005541ec4..93dd2f491a7 100644 --- a/src/java.base/share/classes/java/lang/reflect/Method.java +++ b/src/java.base/share/classes/java/lang/reflect/Method.java @@ -686,9 +686,10 @@ public Object getDefaultValue() { /** * {@inheritDoc} - * @throws NullPointerException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @Override public T getAnnotation(Class annotationClass) { return super.getAnnotation(annotationClass); } @@ -697,6 +698,7 @@ public T getAnnotation(Class annotationClass) { * {@inheritDoc} * @since 1.5 */ + @Override public Annotation[] getDeclaredAnnotations() { return super.getDeclaredAnnotations(); } diff --git a/src/java.base/share/classes/java/lang/reflect/Modifier.java b/src/java.base/share/classes/java/lang/reflect/Modifier.java index 4bb88c272dc..a0980db5e05 100644 --- a/src/java.base/share/classes/java/lang/reflect/Modifier.java +++ b/src/java.base/share/classes/java/lang/reflect/Modifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -377,7 +377,7 @@ static boolean isMandated(int mod) { /** * The Java source modifiers that can be applied to a method. - * @jls8.4.3 Method Modifiers + * @jls 8.4.3 Method Modifiers */ private static final int METHOD_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | @@ -400,9 +400,6 @@ static boolean isMandated(int mod) { private static final int PARAMETER_MODIFIERS = Modifier.FINAL; - /** - * - */ static final int ACCESS_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; diff --git a/src/java.base/share/classes/java/lang/reflect/Parameter.java b/src/java.base/share/classes/java/lang/reflect/Parameter.java index 603ebbbf008..dfa43112300 100644 --- a/src/java.base/share/classes/java/lang/reflect/Parameter.java +++ b/src/java.base/share/classes/java/lang/reflect/Parameter.java @@ -75,6 +75,7 @@ public final class Parameter implements AnnotatedElement { * @param obj The object to compare. * @return Whether or not this is equal to the argument. */ + @Override public boolean equals(Object obj) { if(obj instanceof Parameter) { Parameter other = (Parameter)obj; @@ -90,6 +91,7 @@ public boolean equals(Object obj) { * * @return A hash code based on the executable's hash code. */ + @Override public int hashCode() { return executable.hashCode() ^ index; } @@ -120,6 +122,7 @@ public boolean isNamePresent() { * @return A string representation of the parameter and associated * information. */ + @Override public String toString() { final StringBuilder sb = new StringBuilder(); final Type type = getParameterizedType(); @@ -280,8 +283,11 @@ public boolean isVarArgs() { /** * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. * @throws NullPointerException {@inheritDoc} */ + @Override public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); return annotationClass.cast(declaredAnnotations().get(annotationClass)); @@ -289,6 +295,9 @@ public T getAnnotation(Class annotationClass) { /** * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} */ @Override @@ -300,14 +309,22 @@ public T[] getAnnotationsByType(Class annotationClass) /** * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. */ + @Override public Annotation[] getDeclaredAnnotations() { return executable.getParameterAnnotations()[index]; } /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. + * * @throws NullPointerException {@inheritDoc} */ + @Override public T getDeclaredAnnotation(Class annotationClass) { // Only annotations on classes are inherited, for all other // objects getDeclaredAnnotation is the same as @@ -316,6 +333,10 @@ public T getDeclaredAnnotation(Class annotationClass) } /** + * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. + * * @throws NullPointerException {@inheritDoc} */ @Override @@ -328,7 +349,10 @@ public T[] getDeclaredAnnotationsByType(Class annotati /** * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. */ + @Override public Annotation[] getAnnotations() { return getDeclaredAnnotations(); } diff --git a/src/java.base/share/classes/java/lang/reflect/RecordComponent.java b/src/java.base/share/classes/java/lang/reflect/RecordComponent.java index c9b518f9f3c..7f5b01fb640 100644 --- a/src/java.base/share/classes/java/lang/reflect/RecordComponent.java +++ b/src/java.base/share/classes/java/lang/reflect/RecordComponent.java @@ -180,6 +180,9 @@ public Method getAccessor() { } /** + * {@inheritDoc} + *

Note that any annotation returned by this method is a + * declaration annotation. * @throws NullPointerException {@inheritDoc} */ @Override @@ -215,6 +218,8 @@ private Map, Annotation> declaredAnnotations() { /** * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getAnnotations() { @@ -223,6 +228,8 @@ public Annotation[] getAnnotations() { /** * {@inheritDoc} + *

Note that any annotations returned by this method are + * declaration annotations. */ @Override public Annotation[] getDeclaredAnnotations() { return AnnotationParser.toArray(declaredAnnotations()); }