提交 0ecf4bb6 编写于 作者: J jfranck

8007072: Update Core Reflection for Type Annotations to match latest spec

8022324: j.l.Class.getAnnotatedInterfaces() for array type returns wrong value
8024915: j.l.r.Executable.getAnnotatedReceiverType() should return null for static methods
Summary: Update javadoc and implementation of reflection for type annotations to match latest spec
Reviewed-by: darcy
上级 65895d89
...@@ -3414,16 +3414,20 @@ public final class Class<T> implements java.io.Serializable, ...@@ -3414,16 +3414,20 @@ public final class Class<T> implements java.io.Serializable,
transient ClassValue.ClassValueMap classValueMap; transient ClassValue.ClassValueMap classValueMap;
/** /**
* Returns an AnnotatedType object that represents the use of a type to specify * Returns an {@code AnnotatedType} object that represents the use of a
* the superclass of the entity represented by this Class. (The <em>use</em> of type * type to specify the superclass of the entity represented by this {@code
* Foo to specify the superclass in '... extends Foo' is distinct from the * Class} object. (The <em>use</em> of type Foo to specify the superclass
* <em>declaration</em> of type Foo.) * in '... extends Foo' is distinct from the <em>declaration</em> of type
* Foo.)
* *
* If this Class represents a class type whose declaration does not explicitly * <p> If this {@code Class} object represents a type whose declaration
* indicate an annotated superclass, the return value is null. * does not explicitly indicate an annotated superclass, then the return
* value is an {@code AnnotatedType} object representing an element with no
* annotations.
* *
* If this Class represents either the Object class, an interface type, an * <p> If this {@code Class} represents either the {@code Object} class, an
* array type, a primitive type, or void, the return value is null. * interface type, an array type, a primitive type, or void, the return
* value is {@code null}.
* *
* @return an object representing the superclass * @return an object representing the superclass
* @since 1.8 * @since 1.8
...@@ -3441,29 +3445,32 @@ public final class Class<T> implements java.io.Serializable, ...@@ -3441,29 +3445,32 @@ public final class Class<T> implements java.io.Serializable,
} }
/** /**
* Returns an array of AnnotatedType objects that represent the use of types to * Returns an array of {@code AnnotatedType} objects that represent the use
* specify superinterfaces of the entity represented by this Class. (The <em>use</em> * of types to specify superinterfaces of the entity represented by this
* of type Foo to specify a superinterface in '... implements Foo' is * {@code Class} object. (The <em>use</em> of type Foo to specify a
* distinct from the <em>declaration</em> of type Foo.) * superinterface in '... implements Foo' is distinct from the
* * <em>declaration</em> of type Foo.)
* If this Class represents a class, the return value is an array
* containing objects representing the uses of interface types to specify
* interfaces implemented by the class. The order of the objects in the
* array corresponds to the order of the interface types used in the
* 'implements' clause of the declaration of this Class.
* *
* If this Class represents an interface, the return value is an array * <p> If this {@code Class} object represents a class, the return value is
* containing objects representing the uses of interface types to specify * an array containing objects representing the uses of interface types to
* interfaces directly extended by the interface. The order of the objects in * specify interfaces implemented by the class. The order of the objects in
* the array corresponds to the order of the interface types used in the * the array corresponds to the order of the interface types used in the
* 'extends' clause of the declaration of this Class. * 'implements' clause of the declaration of this {@code Class} object.
* *
* If this Class represents a class or interface whose declaration does not * <p> If this {@code Class} object represents an interface, the return
* explicitly indicate any annotated superinterfaces, the return value is an * value is an array containing objects representing the uses of interface
* array of length 0. * types to specify interfaces directly extended by the interface. The
* order of the objects in the array corresponds to the order of the
* interface types used in the 'extends' clause of the declaration of this
* {@code Class} object.
*
* <p> If this {@code Class} object represents a class or interface whose
* declaration does not explicitly indicate any annotated superinterfaces,
* the return value is an array of length 0.
* *
* If this Class represents either the Object class, an array type, a * <p> If this {@code Class} object represents either the {@code Object}
* primitive type, or void, the return value is an array of length 0. * class, an array type, a primitive type, or void, the return value is an
* array of length 0.
* *
* @return an array representing the superinterfaces * @return an array representing the superinterfaces
* @since 1.8 * @since 1.8
......
...@@ -27,17 +27,18 @@ package java.lang.reflect; ...@@ -27,17 +27,18 @@ package java.lang.reflect;
/** /**
* AnnotatedArrayType represents the use of an array type, whose component * {@code AnnotatedArrayType} represents the potentially annotated use of an
* type may itself represent the annotated use of a type. * array type, whose component type may itself represent the annotated use of a
* type.
* *
* @since 1.8 * @since 1.8
*/ */
public interface AnnotatedArrayType extends AnnotatedType { public interface AnnotatedArrayType extends AnnotatedType {
/** /**
* Returns the annotated generic component type of this array type. * Returns the potentially annotated generic component type of this array type.
* *
* @return the annotated generic component type of this array type * @return the potentially annotated generic component type of this array type
*/ */
AnnotatedType getAnnotatedGenericComponentType(); AnnotatedType getAnnotatedGenericComponentType();
} }
...@@ -26,17 +26,18 @@ ...@@ -26,17 +26,18 @@
package java.lang.reflect; package java.lang.reflect;
/** /**
* AnnotatedParameterizedType represents the use of a parameterized type, * {@code AnnotatedParameterizedType} represents the potentially annotated use
* whose type arguments may themselves represent annotated uses of types. * of a parameterized type, whose type arguments may themselves represent
* annotated uses of types.
* *
* @since 1.8 * @since 1.8
*/ */
public interface AnnotatedParameterizedType extends AnnotatedType { public interface AnnotatedParameterizedType extends AnnotatedType {
/** /**
* Returns the annotated actual type arguments of this parameterized type. * Returns the potentially annotated actual type arguments of this parameterized type.
* *
* @return the annotated actual type arguments of this parameterized type * @return the potentially annotated actual type arguments of this parameterized type
*/ */
AnnotatedType[] getAnnotatedActualTypeArguments(); AnnotatedType[] getAnnotatedActualTypeArguments();
} }
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
package java.lang.reflect; package java.lang.reflect;
/** /**
* AnnotatedType represents the annotated use of a type in the program * {@code AnnotatedType} represents the potentially annotated use of a type in
* currently running in this VM. The use may be of any type in the Java * the program currently running in this VM. The use may be of any type in the
* programming language, including an array type, a parameterized type, a type * Java programming language, including an array type, a parameterized type, a
* variable, or a wildcard type. * type variable, or a wildcard type.
* *
* @since 1.8 * @since 1.8
*/ */
......
...@@ -26,18 +26,18 @@ ...@@ -26,18 +26,18 @@
package java.lang.reflect; package java.lang.reflect;
/** /**
* AnnotatedTypeVariable represents the use of a type variable, whose * {@code AnnotatedTypeVariable} represents the potentially annotated use of a
* declaration may have bounds which themselves represent annotated uses of * type variable, whose declaration may have bounds which themselves represent
* types. * annotated uses of types.
* *
* @since 1.8 * @since 1.8
*/ */
public interface AnnotatedTypeVariable extends AnnotatedType { public interface AnnotatedTypeVariable extends AnnotatedType {
/** /**
* Returns the annotated bounds of this type variable. * Returns the potentially annotated bounds of this type variable.
* *
* @return the annotated bounds of this type variable * @return the potentially annotated bounds of this type variable
*/ */
AnnotatedType[] getAnnotatedBounds(); AnnotatedType[] getAnnotatedBounds();
} }
...@@ -26,24 +26,25 @@ ...@@ -26,24 +26,25 @@
package java.lang.reflect; package java.lang.reflect;
/** /**
* AnnotatedWildcardType represents the use of a wildcard type argument, whose * {@code AnnotatedWildcardType} represents the potentially annotated use of a
* upper or lower bounds may themselves represent annotated uses of types. * wildcard type argument, whose upper or lower bounds may themselves represent
* annotated uses of types.
* *
* @since 1.8 * @since 1.8
*/ */
public interface AnnotatedWildcardType extends AnnotatedType { public interface AnnotatedWildcardType extends AnnotatedType {
/** /**
* Returns the annotated lower bounds of this wildcard type. * Returns the potentially annotated lower bounds of this wildcard type.
* *
* @return the annotated lower bounds of this wildcard type * @return the potentially annotated lower bounds of this wildcard type
*/ */
AnnotatedType[] getAnnotatedLowerBounds(); AnnotatedType[] getAnnotatedLowerBounds();
/** /**
* Returns the annotated upper bounds of this wildcard type. * Returns the potentially annotated upper bounds of this wildcard type.
* *
* @return the annotated upper bounds of this wildcard type * @return the potentially annotated upper bounds of this wildcard type
*/ */
AnnotatedType[] getAnnotatedUpperBounds(); AnnotatedType[] getAnnotatedUpperBounds();
} }
...@@ -514,18 +514,20 @@ public abstract class Executable extends AccessibleObject ...@@ -514,18 +514,20 @@ public abstract class Executable extends AccessibleObject
} }
/** /**
* Returns an AnnotatedType object that represents the use of a type to * Returns an {@code AnnotatedType} object that represents the use of a type to
* specify the return type of the method/constructor represented by this * specify the return type of the method/constructor represented by this
* Executable. * Executable.
* *
* If this Executable represents a constructor, the AnnotatedType object * If this {@code Executable} object represents a constructor, the {@code
* represents the type of the constructed object. * AnnotatedType} object represents the type of the constructed object.
*
* If this {@code Executable} object represents a method, the {@code
* AnnotatedType} object represents the use of a type to specify the return
* type of the method.
* *
* If this Executable represents a method, the AnnotatedType object * @return an object representing the return type of the method
* represents the use of a type to specify the return type of the method. * or constructor represented by this {@code Executable}
* *
* @return an object representing the return type of this method
* or constructor
* @since 1.8 * @since 1.8
*/ */
public abstract AnnotatedType getAnnotatedReturnType(); public abstract AnnotatedType getAnnotatedReturnType();
...@@ -549,24 +551,29 @@ public abstract class Executable extends AccessibleObject ...@@ -549,24 +551,29 @@ public abstract class Executable extends AccessibleObject
} }
/** /**
* Returns an AnnotatedType object that represents the use of a type to * Returns an {@code AnnotatedType} object that represents the use of a
* specify the receiver type of the method/constructor represented by this * type to specify the receiver type of the method/constructor represented
* Executable. The receiver type of a method/constructor is available only * by this Executable object. The receiver type of a method/constructor is
* if the method/constructor declares a formal parameter called 'this'. * available only if the method/constructor has a <em>receiver
* parameter</em> (JLS 8.4.1).
* *
* Returns null if this Executable represents a constructor or instance * If this {@code Executable} object represents a constructor or instance
* method that either declares no formal parameter called 'this', or * method that does not have a receiver parameter, or has a receiver
* declares a formal parameter called 'this' with no annotations on its * parameter with no annotations on its type, then the return value is an
* type. * {@code AnnotatedType} object representing an element with no
* annotations.
* *
* Returns null if this Executable represents a static method. * If this {@code Executable} object represents a static method, then the
* return value is null.
* *
* @return an object representing the receiver type of the * @return an object representing the receiver type of the method or
* method or constructor represented by this Executable * constructor represented by this {@code Executable}
* *
* @since 1.8 * @since 1.8
*/ */
public AnnotatedType getAnnotatedReceiverType() { public AnnotatedType getAnnotatedReceiverType() {
if (Modifier.isStatic(this.getModifiers()))
return null;
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(), return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
sun.misc.SharedSecrets.getJavaLangAccess(). sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()), getConstantPool(getDeclaringClass()),
...@@ -577,8 +584,8 @@ public abstract class Executable extends AccessibleObject ...@@ -577,8 +584,8 @@ public abstract class Executable extends AccessibleObject
} }
/** /**
* Returns an array of AnnotatedType objects that represent the use of * Returns an array of {@code AnnotatedType} objects that represent the use
* types to specify formal parameter types of the method/constructor * of types to specify formal parameter types of the method/constructor
* represented by this Executable. The order of the objects in the array * represented by this Executable. The order of the objects in the array
* corresponds to the order of the formal parameter types in the * corresponds to the order of the formal parameter types in the
* declaration of the method/constructor. * declaration of the method/constructor.
...@@ -587,7 +594,8 @@ public abstract class Executable extends AccessibleObject ...@@ -587,7 +594,8 @@ public abstract class Executable extends AccessibleObject
* parameters. * parameters.
* *
* @return an array of objects representing the types of the * @return an array of objects representing the types of the
* formal parameters of this method or constructor * formal parameters of the method or constructor represented by this
* {@code Executable}
* *
* @since 1.8 * @since 1.8
*/ */
...@@ -602,8 +610,8 @@ public abstract class Executable extends AccessibleObject ...@@ -602,8 +610,8 @@ public abstract class Executable extends AccessibleObject
} }
/** /**
* Returns an array of AnnotatedType objects that represent the use of * Returns an array of {@code AnnotatedType} objects that represent the use
* types to specify the declared exceptions of the method/constructor * of types to specify the declared exceptions of the method/constructor
* represented by this Executable. The order of the objects in the array * represented by this Executable. The order of the objects in the array
* corresponds to the order of the exception types in the declaration of * corresponds to the order of the exception types in the declaration of
* the method/constructor. * the method/constructor.
...@@ -612,7 +620,8 @@ public abstract class Executable extends AccessibleObject ...@@ -612,7 +620,8 @@ public abstract class Executable extends AccessibleObject
* exceptions. * exceptions.
* *
* @return an array of objects representing the declared * @return an array of objects representing the declared
* exceptions of this method or constructor * exceptions of the method or constructor represented by this {@code
* Executable}
* *
* @since 1.8 * @since 1.8
*/ */
......
...@@ -118,6 +118,7 @@ public class AnnotatedTypeFactory { ...@@ -118,6 +118,7 @@ public class AnnotatedTypeFactory {
static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION, static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION,
new TypeAnnotation[0], new TypeAnnotation[0], null); new TypeAnnotation[0], new TypeAnnotation[0], null);
static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0];
private static class AnnotatedTypeBaseImpl implements AnnotatedType { private static class AnnotatedTypeBaseImpl implements AnnotatedType {
private final Type type; private final Type type;
......
...@@ -174,6 +174,11 @@ public class TypeAnnotationParser { ...@@ -174,6 +174,11 @@ public class TypeAnnotationParser {
public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations, public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations,
ConstantPool cp, ConstantPool cp,
Class<?> decl) { Class<?> decl) {
if (decl == Object.class ||
decl.isArray() ||
decl.isPrimitive() ||
decl == Void.TYPE)
return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY;
return buildAnnotatedTypes(rawAnnotations, return buildAnnotatedTypes(rawAnnotations,
cp, cp,
decl, decl,
......
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8022324
* @summary Test Class.getAnnotatedInterfaces() returns 0-length array as
* specified.
*/
import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
public class GetAnnotatedInterfaces {
private static final Class<?>[] testData = {
GetAnnotatedInterfaces.class,
(new Clz() {}).getClass(),
(new Object() {}).getClass(),
Object[].class,
Object[][].class,
Object[][][].class,
Object.class,
void.class,
int.class,
};
private static int failed = 0;
private static int tests = 0;
public static void main(String[] args) throws Exception {
testReturnsZeroLengthArray();
if (failed != 0)
throw new RuntimeException("Test failed, check log for details");
if (tests != 9)
throw new RuntimeException("Not all cases ran, failing");
}
private static void testReturnsZeroLengthArray() {
for (Class<?> toTest : testData) {
tests++;
AnnotatedType[] res = toTest.getAnnotatedInterfaces();
if (res == null) {
failed++;
System.out.println(toTest + ".class.getAnnotatedInterface() returns" +
"'null' should zero length array");
} else if (res.length != 0) {
failed++;
System.out.println(toTest + ".class.getAnnotatedInterfaces() returns: "
+ Arrays.asList(res) + ", should be a zero length array of AnnotatedType");
}
}
}
interface If {}
static abstract class Clz {}
}
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8024915
*/
import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
public class GetAnnotatedReceiverType {
public void method() {}
public void method0(GetAnnotatedReceiverType this) {}
public static void method4() {}
class Inner0 {
public Inner0() {}
}
class Inner1 {
public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {}
}
private static int failures = 0;
private static int tests = 0;
public static void main(String[] args) throws NoSuchMethodException {
checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method").getAnnotatedReceiverType(),
"getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType");
checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(),
"getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0").getAnnotatedReceiverType(),
"getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType");
checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(),
"getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType");
checkNull(GetAnnotatedReceiverType.class.getMethod("method4").getAnnotatedReceiverType(),
"getAnnotatedReceiverType() on a static method should return null");
if (failures != 0)
throw new RuntimeException("Test failed, see log for details");
else if (tests != 5)
throw new RuntimeException("Not all cases ran, failing");
}
private static void checkNull(Object o, String msg) {
if (o != null) {
failures++;
System.err.println(msg);
}
tests++;
}
private static void checkEmptyAT(AnnotatedType a, String msg) {
if (a.getAnnotations().length != 0) {
failures++;
System.err.print(msg);
}
tests++;
}
}
...@@ -23,12 +23,16 @@ ...@@ -23,12 +23,16 @@
/* /*
* @test * @test
* @bug 8022343 * @bug 8022343 8007072
* @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so * @summary Test Class.getAnnotatedSuperclass() returns null/non-null
* AnnotatedType as specified
*/ */
import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
public class GetAnnotatedSuperclass { public class GetAnnotatedSuperclass {
private static final Class<?>[] testData = { private static final Class<?>[] nullTestData = {
Object.class, Object.class,
If.class, If.class,
Object[].class, Object[].class,
...@@ -36,9 +40,31 @@ public class GetAnnotatedSuperclass { ...@@ -36,9 +40,31 @@ public class GetAnnotatedSuperclass {
int.class, int.class,
}; };
private static final Class<?>[] nonNullTestData = {
Class.class,
GetAnnotatedSuperclass.class,
(new If() {}).getClass(),
(new Clz() {}).getClass(),
(new Object() {}).getClass(),
};
private static int failed = 0;
private static int tests = 0;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
int failed = 0; testReturnsNull();
for (Class<?> toTest : testData) { testReturnsEmptyAT();
if (failed != 0)
throw new RuntimeException("Test failed, check log for details");
if (tests != 10)
throw new RuntimeException("Not all cases ran, failing");
}
private static void testReturnsNull() {
for (Class<?> toTest : nullTestData) {
tests++;
Object res = toTest.getAnnotatedSuperclass(); Object res = toTest.getAnnotatedSuperclass();
if (res != null) { if (res != null) {
...@@ -47,10 +73,26 @@ public class GetAnnotatedSuperclass { ...@@ -47,10 +73,26 @@ public class GetAnnotatedSuperclass {
+ res + ", should be null"); + res + ", should be null");
} }
} }
}
if (failed != 0) private static void testReturnsEmptyAT() {
throw new RuntimeException("Test failed, check log for details"); for (Class<?> toTest : nonNullTestData) {
tests++;
AnnotatedType res = toTest.getAnnotatedSuperclass();
if (res == null) {
failed++;
System.out.println(toTest + ".getAnnotatedSuperclass() returns 'null' should be non-null");
} else if (res.getAnnotations().length != 0) {
failed++;
System.out.println(toTest + ".getAnnotatedSuperclass() returns: "
+ Arrays.asList(res.getAnnotations()) + ", should be an empty AnnotatedType");
}
}
} }
interface If {} interface If {}
static abstract class Clz {}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册