Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
6f3e485f
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
6f3e485f
编写于
1月 29, 2013
作者:
J
jfranck
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8004698: Implement Core Reflection for Type Annotations
Reviewed-by: darcy
上级
6a3cc7d7
变更
25
展开全部
隐藏空白更改
内联
并排
Showing
25 changed file
with
2106 addition
and
29 deletion
+2106
-29
src/share/classes/java/lang/Class.java
src/share/classes/java/lang/Class.java
+56
-0
src/share/classes/java/lang/System.java
src/share/classes/java/lang/System.java
+8
-1
src/share/classes/java/lang/reflect/AnnotatedArrayType.java
src/share/classes/java/lang/reflect/AnnotatedArrayType.java
+43
-0
src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java
...classes/java/lang/reflect/AnnotatedParameterizedType.java
+42
-0
src/share/classes/java/lang/reflect/AnnotatedType.java
src/share/classes/java/lang/reflect/AnnotatedType.java
+44
-0
src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java
...hare/classes/java/lang/reflect/AnnotatedTypeVariable.java
+43
-0
src/share/classes/java/lang/reflect/AnnotatedWildcardType.java
...hare/classes/java/lang/reflect/AnnotatedWildcardType.java
+49
-0
src/share/classes/java/lang/reflect/Constructor.java
src/share/classes/java/lang/reflect/Constructor.java
+12
-0
src/share/classes/java/lang/reflect/Executable.java
src/share/classes/java/lang/reflect/Executable.java
+86
-1
src/share/classes/java/lang/reflect/Field.java
src/share/classes/java/lang/reflect/Field.java
+19
-2
src/share/classes/java/lang/reflect/Method.java
src/share/classes/java/lang/reflect/Method.java
+12
-0
src/share/classes/java/lang/reflect/ReflectAccess.java
src/share/classes/java/lang/reflect/ReflectAccess.java
+5
-1
src/share/classes/java/lang/reflect/TypeVariable.java
src/share/classes/java/lang/reflect/TypeVariable.java
+13
-1
src/share/classes/sun/misc/JavaLangAccess.java
src/share/classes/sun/misc/JavaLangAccess.java
+14
-1
src/share/classes/sun/reflect/LangReflectAccess.java
src/share/classes/sun/reflect/LangReflectAccess.java
+4
-1
src/share/classes/sun/reflect/ReflectionFactory.java
src/share/classes/sun/reflect/ReflectionFactory.java
+8
-1
src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java
.../classes/sun/reflect/annotation/AnnotatedTypeFactory.java
+320
-0
src/share/classes/sun/reflect/annotation/AnnotationParser.java
...hare/classes/sun/reflect/annotation/AnnotationParser.java
+2
-2
src/share/classes/sun/reflect/annotation/TypeAnnotation.java
src/share/classes/sun/reflect/annotation/TypeAnnotation.java
+227
-0
src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
.../classes/sun/reflect/annotation/TypeAnnotationParser.java
+491
-0
src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
.../reflect/generics/reflectiveObjects/TypeVariableImpl.java
+51
-16
src/share/javavm/export/jvm.h
src/share/javavm/export/jvm.h
+6
-0
src/share/native/java/lang/Class.c
src/share/native/java/lang/Class.c
+3
-2
test/java/lang/annotation/TypeAnnotationReflection.java
test/java/lang/annotation/TypeAnnotationReflection.java
+428
-0
test/java/lang/annotation/TypeParamAnnotation.java
test/java/lang/annotation/TypeParamAnnotation.java
+120
-0
未找到文件。
src/share/classes/java/lang/Class.java
浏览文件 @
6f3e485f
...
@@ -29,12 +29,14 @@ import java.lang.reflect.Array;
...
@@ -29,12 +29,14 @@ import java.lang.reflect.Array;
import
java.lang.reflect.GenericArrayType
;
import
java.lang.reflect.GenericArrayType
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Executable
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.TypeVariable
;
import
java.lang.reflect.TypeVariable
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.AnnotatedType
;
import
java.lang.ref.SoftReference
;
import
java.lang.ref.SoftReference
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.ObjectStreamField
;
import
java.io.ObjectStreamField
;
...
@@ -2325,6 +2327,11 @@ public final
...
@@ -2325,6 +2327,11 @@ public final
// Annotations handling
// Annotations handling
private
native
byte
[]
getRawAnnotations
();
private
native
byte
[]
getRawAnnotations
();
// Since 1.8
native
byte
[]
getRawTypeAnnotations
();
static
byte
[]
getExecutableTypeAnnotationBytes
(
Executable
ex
)
{
return
getReflectionFactory
().
getExecutableTypeAnnotationBytes
(
ex
);
}
native
ConstantPool
getConstantPool
();
native
ConstantPool
getConstantPool
();
...
@@ -3196,4 +3203,53 @@ public final
...
@@ -3196,4 +3203,53 @@ public final
* Maintained by the ClassValue class.
* Maintained by the ClassValue class.
*/
*/
transient
ClassValue
.
ClassValueMap
classValueMap
;
transient
ClassValue
.
ClassValueMap
classValueMap
;
/**
* Returns an AnnotatedType object that represents the use of a type to specify
* the superclass of the entity represented by this Class. (The <em>use</em> of type
* Foo to specify the superclass 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
* indicate an annotated superclass, the return value is null.
*
* If this Class represents either the Object class, an interface type, an
* array type, a primitive type, or void, the return value is null.
*
* @since 1.8
*/
public
AnnotatedType
getAnnotatedSuperclass
()
{
return
TypeAnnotationParser
.
buildAnnotatedSuperclass
(
getRawTypeAnnotations
(),
getConstantPool
(),
this
);
}
/**
* Returns an array of AnnotatedType objects that represent the use of types to
* specify superinterfaces of the entity represented by this Class. (The <em>use</em>
* of type Foo to specify a 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
* containing objects representing the uses of interface 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 Class.
*
* If this Class 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
* primitive type, or void, the return value is an array of length 0.
*
* @since 1.8
*/
public
AnnotatedType
[]
getAnnotatedInterfaces
()
{
return
TypeAnnotationParser
.
buildAnnotatedInterfaces
(
getRawTypeAnnotations
(),
getConstantPool
(),
this
);
}
}
}
src/share/classes/java/lang/System.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 1994, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -26,6 +26,7 @@ package java.lang;
...
@@ -26,6 +26,7 @@ package java.lang;
import
java.io.*
;
import
java.io.*
;
import
java.lang.annotation.Annotation
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Executable
;
import
java.util.Properties
;
import
java.util.Properties
;
import
java.util.PropertyPermission
;
import
java.util.PropertyPermission
;
import
java.util.StringTokenizer
;
import
java.util.StringTokenizer
;
...
@@ -1199,6 +1200,12 @@ public final class System {
...
@@ -1199,6 +1200,12 @@ public final class System {
public
<
A
extends
Annotation
>
A
getDirectDeclaredAnnotation
(
Class
<?>
klass
,
Class
<
A
>
anno
)
{
public
<
A
extends
Annotation
>
A
getDirectDeclaredAnnotation
(
Class
<?>
klass
,
Class
<
A
>
anno
)
{
return
klass
.
getDirectDeclaredAnnotation
(
anno
);
return
klass
.
getDirectDeclaredAnnotation
(
anno
);
}
}
public
byte
[]
getRawClassTypeAnnotations
(
Class
<?>
klass
)
{
return
klass
.
getRawTypeAnnotations
();
}
public
byte
[]
getRawExecutableTypeAnnotations
(
Executable
executable
)
{
return
Class
.
getExecutableTypeAnnotationBytes
(
executable
);
}
public
<
E
extends
Enum
<
E
>>
public
<
E
extends
Enum
<
E
>>
E
[]
getEnumConstantsShared
(
Class
<
E
>
klass
)
{
E
[]
getEnumConstantsShared
(
Class
<
E
>
klass
)
{
return
klass
.
getEnumConstantsShared
();
return
klass
.
getEnumConstantsShared
();
...
...
src/share/classes/java/lang/reflect/AnnotatedArrayType.java
0 → 100644
浏览文件 @
6f3e485f
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.reflect
;
/**
* AnnotatedArrayType represents the use of an array type, whose component
* type may itself represent the annotated use of a type.
*
* @since 1.8
*/
public
interface
AnnotatedArrayType
extends
AnnotatedType
{
/**
* Returns the annotated generic component type of this array type.
*
* @return the annotated generic component type of this array type
*/
AnnotatedType
getAnnotatedGenericComponentType
();
}
src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java
0 → 100644
浏览文件 @
6f3e485f
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.reflect
;
/**
* AnnotatedParameterizedType represents the use of a parameterized type,
* whose type arguments may themselves represent annotated uses of types.
*
* @since 1.8
*/
public
interface
AnnotatedParameterizedType
extends
AnnotatedType
{
/**
* Returns the annotated actual type arguments of this parameterized type.
*
* @return the annotated actual type arguments of this parameterized type
*/
AnnotatedType
[]
getAnnotatedActualTypeArguments
();
}
src/share/classes/java/lang/reflect/AnnotatedType.java
0 → 100644
浏览文件 @
6f3e485f
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.reflect
;
/**
* AnnotatedType represents the 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.
*
* @since 1.8
*/
public
interface
AnnotatedType
extends
AnnotatedElement
{
/**
* Returns the underlying type that this annotated type represents.
*
* @return the type this annotated type represents
*/
public
Type
getType
();
}
src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java
0 → 100644
浏览文件 @
6f3e485f
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.reflect
;
/**
* AnnotatedTypeVariable represents the use of a type variable, whose
* declaration may have bounds which themselves represent annotated uses of
* types.
*
* @since 1.8
*/
public
interface
AnnotatedTypeVariable
extends
AnnotatedType
{
/**
* Returns the annotated bounds of this type variable.
*
* @return the annotated bounds of this type variable
*/
AnnotatedType
[]
getAnnotatedBounds
();
}
src/share/classes/java/lang/reflect/AnnotatedWildcardType.java
0 → 100644
浏览文件 @
6f3e485f
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
java.lang.reflect
;
/**
* AnnotatedWildcardType represents the use of a wildcard type argument, whose
* upper or lower bounds may themselves represent annotated uses of types.
*
* @since 1.8
*/
public
interface
AnnotatedWildcardType
extends
AnnotatedType
{
/**
* Returns the annotated lower bounds of this wildcard type.
*
* @return the annotated lower bounds of this wildcard type
*/
AnnotatedType
[]
getAnnotatedLowerBounds
();
/**
* Returns the annotated upper bounds of this wildcard type.
*
* @return the annotated upper bounds of this wildcard type
*/
AnnotatedType
[]
getAnnotatedUpperBounds
();
}
src/share/classes/java/lang/reflect/Constructor.java
浏览文件 @
6f3e485f
...
@@ -154,6 +154,10 @@ public final class Constructor<T> extends Executable {
...
@@ -154,6 +154,10 @@ public final class Constructor<T> extends Executable {
byte
[]
getAnnotationBytes
()
{
byte
[]
getAnnotationBytes
()
{
return
annotations
;
return
annotations
;
}
}
@Override
byte
[]
getTypeAnnotationBytes
()
{
return
typeAnnotations
;
}
/**
/**
* {@inheritDoc}
* {@inheritDoc}
...
@@ -523,4 +527,12 @@ public final class Constructor<T> extends Executable {
...
@@ -523,4 +527,12 @@ public final class Constructor<T> extends Executable {
}
}
}
}
}
}
/**
* {@inheritDoc}
* @since 1.8
*/
public
AnnotatedType
getAnnotatedReturnType
()
{
return
getAnnotatedReturnType0
(
getDeclaringClass
());
}
}
}
src/share/classes/java/lang/reflect/Executable.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 201
2, 201
3, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -31,6 +31,8 @@ import java.util.Map;
...
@@ -31,6 +31,8 @@ import java.util.Map;
import
java.util.Objects
;
import
java.util.Objects
;
import
sun.reflect.annotation.AnnotationParser
;
import
sun.reflect.annotation.AnnotationParser
;
import
sun.reflect.annotation.AnnotationSupport
;
import
sun.reflect.annotation.AnnotationSupport
;
import
sun.reflect.annotation.TypeAnnotationParser
;
import
sun.reflect.annotation.TypeAnnotation
;
import
sun.reflect.generics.repository.ConstructorRepository
;
import
sun.reflect.generics.repository.ConstructorRepository
;
/**
/**
...
@@ -50,6 +52,7 @@ public abstract class Executable extends AccessibleObject
...
@@ -50,6 +52,7 @@ public abstract class Executable extends AccessibleObject
* Accessor method to allow code sharing
* Accessor method to allow code sharing
*/
*/
abstract
byte
[]
getAnnotationBytes
();
abstract
byte
[]
getAnnotationBytes
();
abstract
byte
[]
getTypeAnnotationBytes
();
/**
/**
* Does the Executable have generic information.
* Does the Executable have generic information.
...
@@ -470,4 +473,86 @@ public abstract class Executable extends AccessibleObject
...
@@ -470,4 +473,86 @@ public abstract class Executable extends AccessibleObject
return
declaredAnnotations
;
return
declaredAnnotations
;
}
}
/* Helper for subclasses of Executable.
*
* Returns an AnnotatedType object that represents the use of a type to
* specify the return type of the method/constructor represented by this
* Executable.
*
* @since 1.8
*/
AnnotatedType
getAnnotatedReturnType0
(
Type
returnType
)
{
return
TypeAnnotationParser
.
buildAnnotatedType
(
getTypeAnnotationBytes
(),
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
getConstantPool
(
getDeclaringClass
()),
this
,
getDeclaringClass
(),
returnType
,
TypeAnnotation
.
TypeAnnotationTarget
.
METHOD_RETURN_TYPE
);
}
/**
* Returns an AnnotatedType object that represents the use of a type to
* specify the receiver type of the method/constructor represented by this
* Executable. The receiver type of a method/constructor is available only
* if the method/constructor declares a formal parameter called 'this'.
*
* Returns null if this Executable represents a constructor or instance
* method that either declares no formal parameter called 'this', or
* declares a formal parameter called 'this' with no annotations on its
* type.
*
* Returns null if this Executable represents a static method.
*
* @since 1.8
*/
public
AnnotatedType
getAnnotatedReceiverType
()
{
return
TypeAnnotationParser
.
buildAnnotatedType
(
getTypeAnnotationBytes
(),
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
getConstantPool
(
getDeclaringClass
()),
this
,
getDeclaringClass
(),
getDeclaringClass
(),
TypeAnnotation
.
TypeAnnotationTarget
.
METHOD_RECEIVER_TYPE
);
}
/**
* Returns an array of AnnotatedType objects that represent the use of
* types to specify formal parameter types of the method/constructor
* represented by this Executable. The order of the objects in the array
* corresponds to the order of the formal parameter types in the
* declaration of the method/constructor.
*
* Returns an array of length 0 if the method/constructor declares no
* parameters.
*
* @since 1.8
*/
public
AnnotatedType
[]
getAnnotatedParameterTypes
()
{
throw
new
UnsupportedOperationException
(
"Not yet"
);
}
/**
* Returns an array of AnnotatedType objects that represent the use of
* types to specify the declared exceptions of the method/constructor
* represented by this Executable. The order of the objects in the array
* corresponds to the order of the exception types in the declaration of
* the method/constructor.
*
* Returns an array of length 0 if the method/constructor declares no
* exceptions.
*
* @since 1.8
*/
public
AnnotatedType
[]
getAnnotatedExceptionTypes
()
{
return
TypeAnnotationParser
.
buildAnnotatedTypes
(
getTypeAnnotationBytes
(),
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
getConstantPool
(
getDeclaringClass
()),
this
,
getDeclaringClass
(),
getGenericExceptionTypes
(),
TypeAnnotation
.
TypeAnnotationTarget
.
THROWS
);
}
}
}
src/share/classes/java/lang/reflect/Field.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 1996, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -36,7 +36,8 @@ import java.util.Map;
...
@@ -36,7 +36,8 @@ import java.util.Map;
import
java.util.Objects
;
import
java.util.Objects
;
import
sun.reflect.annotation.AnnotationParser
;
import
sun.reflect.annotation.AnnotationParser
;
import
sun.reflect.annotation.AnnotationSupport
;
import
sun.reflect.annotation.AnnotationSupport
;
import
sun.reflect.annotation.TypeAnnotation
;
import
sun.reflect.annotation.TypeAnnotationParser
;
/**
/**
* A {@code Field} provides information about, and dynamic access to, a
* A {@code Field} provides information about, and dynamic access to, a
...
@@ -1053,4 +1054,20 @@ class Field extends AccessibleObject implements Member {
...
@@ -1053,4 +1054,20 @@ class Field extends AccessibleObject implements Member {
}
}
return
declaredAnnotations
;
return
declaredAnnotations
;
}
}
/**
* Returns an AnnotatedType object that represents the use of a type to specify
* the declared type of the field represented by this Field.
*
* @since 1.8
*/
public
AnnotatedType
getAnnotatedType
()
{
return
TypeAnnotationParser
.
buildAnnotatedType
(
typeAnnotations
,
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
getConstantPool
(
getDeclaringClass
()),
this
,
getDeclaringClass
(),
getGenericType
(),
TypeAnnotation
.
TypeAnnotationTarget
.
FIELD_TYPE
);
}
}
}
src/share/classes/java/lang/reflect/Method.java
浏览文件 @
6f3e485f
...
@@ -165,6 +165,10 @@ public final class Method extends Executable {
...
@@ -165,6 +165,10 @@ public final class Method extends Executable {
byte
[]
getAnnotationBytes
()
{
byte
[]
getAnnotationBytes
()
{
return
annotations
;
return
annotations
;
}
}
@Override
byte
[]
getTypeAnnotationBytes
()
{
return
typeAnnotations
;
}
/**
/**
* {@inheritDoc}
* {@inheritDoc}
...
@@ -621,6 +625,14 @@ public final class Method extends Executable {
...
@@ -621,6 +625,14 @@ public final class Method extends Executable {
return
sharedGetParameterAnnotations
(
parameterTypes
,
parameterAnnotations
);
return
sharedGetParameterAnnotations
(
parameterTypes
,
parameterAnnotations
);
}
}
/**
* {@inheritDoc}
* @since 1.8
*/
public
AnnotatedType
getAnnotatedReturnType
()
{
return
getAnnotatedReturnType0
(
getGenericReturnType
());
}
@Override
@Override
void
handleParameterNumberMismatch
(
int
resultLength
,
int
numParameters
)
{
void
handleParameterNumberMismatch
(
int
resultLength
,
int
numParameters
)
{
throw
new
AnnotationFormatError
(
"Parameter annotations don't match number of parameters"
);
throw
new
AnnotationFormatError
(
"Parameter annotations don't match number of parameters"
);
...
...
src/share/classes/java/lang/reflect/ReflectAccess.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2001, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -128,6 +128,10 @@ class ReflectAccess implements sun.reflect.LangReflectAccess {
...
@@ -128,6 +128,10 @@ class ReflectAccess implements sun.reflect.LangReflectAccess {
return
c
.
getRawParameterAnnotations
();
return
c
.
getRawParameterAnnotations
();
}
}
public
byte
[]
getExecutableTypeAnnotationBytes
(
Executable
ex
)
{
return
ex
.
getTypeAnnotationBytes
();
}
//
//
// Copying routines, needed to quickly fabricate new Field,
// Copying routines, needed to quickly fabricate new Field,
// Method, and Constructor objects from templates
// Method, and Constructor objects from templates
...
...
src/share/classes/java/lang/reflect/TypeVariable.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2003, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -86,4 +86,16 @@ public interface TypeVariable<D extends GenericDeclaration> extends Type, Annota
...
@@ -86,4 +86,16 @@ public interface TypeVariable<D extends GenericDeclaration> extends Type, Annota
* @return the name of this type variable, as it appears in the source code
* @return the name of this type variable, as it appears in the source code
*/
*/
String
getName
();
String
getName
();
/**
* Returns an array of AnnotatedType objects that represent the use of
* types to denote the upper bounds of the type parameter represented by
* this TypeVariable. The order of the objects in the array corresponds to
* the order of the bounds in the declaration of the type parameter.
*
* Returns an array of length 0 if the type parameter declares no bounds.
*
* @since 1.8
*/
AnnotatedType
[]
getAnnotatedBounds
();
}
}
src/share/classes/sun/misc/JavaLangAccess.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
package
sun.misc
;
package
sun.misc
;
import
java.lang.annotation.Annotation
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Executable
;
import
sun.reflect.ConstantPool
;
import
sun.reflect.ConstantPool
;
import
sun.reflect.annotation.AnnotationType
;
import
sun.reflect.annotation.AnnotationType
;
import
sun.nio.ch.Interruptible
;
import
sun.nio.ch.Interruptible
;
...
@@ -46,6 +47,18 @@ public interface JavaLangAccess {
...
@@ -46,6 +47,18 @@ public interface JavaLangAccess {
*/
*/
AnnotationType
getAnnotationType
(
Class
<?>
klass
);
AnnotationType
getAnnotationType
(
Class
<?>
klass
);
/**
* Get the array of bytes that is the class-file representation
* of this Class' type annotations.
*/
byte
[]
getRawClassTypeAnnotations
(
Class
<?>
klass
);
/**
* Get the array of bytes that is the class-file representation
* of this Executable's type annotations.
*/
byte
[]
getRawExecutableTypeAnnotations
(
Executable
executable
);
/**
/**
* Returns the elements of an enum class or null if the
* Returns the elements of an enum class or null if the
* Class object does not represent an enum type;
* Class object does not represent an enum type;
...
...
src/share/classes/sun/reflect/LangReflectAccess.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2001, 20
04
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 20
13
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -81,6 +81,9 @@ public interface LangReflectAccess {
...
@@ -81,6 +81,9 @@ public interface LangReflectAccess {
public
void
setConstructorAccessor
(
Constructor
<?>
c
,
public
void
setConstructorAccessor
(
Constructor
<?>
c
,
ConstructorAccessor
accessor
);
ConstructorAccessor
accessor
);
/** Gets the byte[] that encodes TypeAnnotations on an Executable. */
public
byte
[]
getExecutableTypeAnnotationBytes
(
Executable
ex
);
/** Gets the "slot" field from a Constructor (used for serialization) */
/** Gets the "slot" field from a Constructor (used for serialization) */
public
int
getConstructorSlot
(
Constructor
<?>
c
);
public
int
getConstructorSlot
(
Constructor
<?>
c
);
...
...
src/share/classes/sun/reflect/ReflectionFactory.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2001, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
package
sun.reflect
;
package
sun.reflect
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Executable
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Modifier
;
...
@@ -314,6 +315,12 @@ public class ReflectionFactory {
...
@@ -314,6 +315,12 @@ public class ReflectionFactory {
return
langReflectAccess
().
copyConstructor
(
arg
);
return
langReflectAccess
().
copyConstructor
(
arg
);
}
}
/** Gets the byte[] that encodes TypeAnnotations on an executable.
*/
public
byte
[]
getExecutableTypeAnnotationBytes
(
Executable
ex
)
{
return
langReflectAccess
().
getExecutableTypeAnnotationBytes
(
ex
);
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
//
// Routines used by serialization
// Routines used by serialization
...
...
src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java
0 → 100644
浏览文件 @
6f3e485f
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
sun.reflect.annotation
;
import
java.lang.annotation.*
;
import
java.lang.reflect.*
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
import
static
sun
.
reflect
.
annotation
.
TypeAnnotation
.*;
public
class
AnnotatedTypeFactory
{
/**
* Create an AnnotatedType.
*
* @param type the type this AnnotatedType corresponds to
* @param currentLoc the location this AnnotatedType corresponds to
* @param actualTypeAnnos the type annotations this AnnotatedType has
* @param allOnSameTarget all type annotation on the same TypeAnnotationTarget
* as the AnnotatedType being built
* @param decl the declaration having the type use this AnnotatedType
* corresponds to
*/
public
static
AnnotatedType
buildAnnotatedType
(
Type
type
,
LocationInfo
currentLoc
,
TypeAnnotation
[]
actualTypeAnnos
,
TypeAnnotation
[]
allOnSameTarget
,
AnnotatedElement
decl
)
{
if
(
type
==
null
)
{
return
EMPTY_ANNOTATED_TYPE
;
}
if
(
isArray
(
type
))
return
new
AnnotatedArrayTypeImpl
(
type
,
currentLoc
,
actualTypeAnnos
,
allOnSameTarget
,
decl
);
if
(
type
instanceof
Class
)
{
return
new
AnnotatedTypeBaseImpl
(
type
,
addNesting
(
type
,
currentLoc
),
actualTypeAnnos
,
allOnSameTarget
,
decl
);
}
else
if
(
type
instanceof
TypeVariable
)
{
return
new
AnnotatedTypeVariableImpl
((
TypeVariable
)
type
,
currentLoc
,
actualTypeAnnos
,
allOnSameTarget
,
decl
);
}
else
if
(
type
instanceof
ParameterizedType
)
{
return
new
AnnotatedParameterizedTypeImpl
((
ParameterizedType
)
type
,
addNesting
(
type
,
currentLoc
),
actualTypeAnnos
,
allOnSameTarget
,
decl
);
}
else
if
(
type
instanceof
WildcardType
)
{
return
new
AnnotatedWildcardTypeImpl
((
WildcardType
)
type
,
currentLoc
,
actualTypeAnnos
,
allOnSameTarget
,
decl
);
}
throw
new
AssertionError
(
"Unknown instance of Type: "
+
type
+
"\nThis should not happen."
);
}
private
static
LocationInfo
addNesting
(
Type
type
,
LocationInfo
addTo
)
{
if
(
isArray
(
type
))
return
addTo
;
if
(
type
instanceof
Class
)
{
Class
<?>
clz
=
(
Class
)
type
;
if
(
clz
.
getEnclosingClass
()
==
null
)
return
addTo
;
return
addNesting
(
clz
.
getEnclosingClass
(),
addTo
.
pushInner
());
}
else
if
(
type
instanceof
ParameterizedType
)
{
ParameterizedType
t
=
(
ParameterizedType
)
type
;
if
(
t
.
getOwnerType
()
==
null
)
return
addTo
;
return
addNesting
(
t
.
getOwnerType
(),
addTo
.
pushInner
());
}
return
addTo
;
}
private
static
boolean
isArray
(
Type
t
)
{
if
(
t
instanceof
Class
)
{
Class
<?>
c
=
(
Class
)
t
;
if
(
c
.
isArray
())
return
true
;
}
else
if
(
t
instanceof
GenericArrayType
)
{
return
true
;
}
return
false
;
}
static
final
AnnotatedType
EMPTY_ANNOTATED_TYPE
=
new
AnnotatedTypeBaseImpl
(
null
,
LocationInfo
.
BASE_LOCATION
,
new
TypeAnnotation
[
0
],
new
TypeAnnotation
[
0
],
null
);
private
static
class
AnnotatedTypeBaseImpl
implements
AnnotatedType
{
private
final
Type
type
;
private
final
AnnotatedElement
decl
;
private
final
LocationInfo
location
;
private
final
TypeAnnotation
[]
allOnSameTargetTypeAnnotations
;
private
final
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
annotations
;
AnnotatedTypeBaseImpl
(
Type
type
,
LocationInfo
location
,
TypeAnnotation
[]
actualTypeAnnotations
,
TypeAnnotation
[]
allOnSameTargetTypeAnnotations
,
AnnotatedElement
decl
)
{
this
.
type
=
type
;
this
.
decl
=
decl
;
this
.
location
=
location
;
this
.
allOnSameTargetTypeAnnotations
=
allOnSameTargetTypeAnnotations
;
this
.
annotations
=
TypeAnnotationParser
.
mapTypeAnnotations
(
location
.
filter
(
actualTypeAnnotations
));
}
// AnnotatedElement
@Override
public
final
boolean
isAnnotationPresent
(
Class
<?
extends
Annotation
>
annotation
)
{
return
annotations
.
get
(
annotation
)
!=
null
;
}
@Override
public
final
Annotation
[]
getAnnotations
()
{
return
getDeclaredAnnotations
();
}
@Override
public
final
<
T
extends
Annotation
>
T
getAnnotation
(
Class
<
T
>
annotation
)
{
return
getDeclaredAnnotation
(
annotation
);
}
@Override
public
final
<
T
extends
Annotation
>
T
[]
getAnnotations
(
Class
<
T
>
annotation
)
{
return
getDeclaredAnnotations
(
annotation
);
}
@Override
public
Annotation
[]
getDeclaredAnnotations
()
{
return
annotations
.
values
().
toArray
(
new
Annotation
[
0
]);
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
<
T
extends
Annotation
>
T
getDeclaredAnnotation
(
Class
<
T
>
annotation
)
{
return
(
T
)
annotations
.
get
(
annotation
);
}
@Override
public
<
T
extends
Annotation
>
T
[]
getDeclaredAnnotations
(
Class
<
T
>
annotation
)
{
return
AnnotationSupport
.
getMultipleAnnotations
(
annotations
,
annotation
);
}
// AnnotatedType
@Override
public
Type
getType
()
{
return
type
;
}
// Implementation details
LocationInfo
getLocation
()
{
return
location
;
}
TypeAnnotation
[]
getTypeAnnotations
()
{
return
allOnSameTargetTypeAnnotations
;
}
AnnotatedElement
getDecl
()
{
return
decl
;
}
}
private
static
class
AnnotatedArrayTypeImpl
extends
AnnotatedTypeBaseImpl
implements
AnnotatedArrayType
{
AnnotatedArrayTypeImpl
(
Type
type
,
LocationInfo
location
,
TypeAnnotation
[]
actualTypeAnnotations
,
TypeAnnotation
[]
allOnSameTargetTypeAnnotations
,
AnnotatedElement
decl
)
{
super
(
type
,
location
,
actualTypeAnnotations
,
allOnSameTargetTypeAnnotations
,
decl
);
}
@Override
public
AnnotatedType
getAnnotatedGenericComponentType
()
{
return
AnnotatedTypeFactory
.
buildAnnotatedType
(
getComponentType
(),
getLocation
().
pushArray
(),
getTypeAnnotations
(),
getTypeAnnotations
(),
getDecl
());
}
private
Type
getComponentType
()
{
Type
t
=
getType
();
if
(
t
instanceof
Class
)
{
Class
<?>
c
=
(
Class
)
t
;
return
c
.
getComponentType
();
}
return
((
GenericArrayType
)
t
).
getGenericComponentType
();
}
}
private
static
class
AnnotatedTypeVariableImpl
extends
AnnotatedTypeBaseImpl
implements
AnnotatedTypeVariable
{
AnnotatedTypeVariableImpl
(
TypeVariable
<?>
type
,
LocationInfo
location
,
TypeAnnotation
[]
actualTypeAnnotations
,
TypeAnnotation
[]
allOnSameTargetTypeAnnotations
,
AnnotatedElement
decl
)
{
super
(
type
,
location
,
actualTypeAnnotations
,
allOnSameTargetTypeAnnotations
,
decl
);
}
@Override
public
AnnotatedType
[]
getAnnotatedBounds
()
{
return
getTypeVariable
().
getAnnotatedBounds
();
}
private
TypeVariable
<?>
getTypeVariable
()
{
return
(
TypeVariable
)
getType
();
}
}
private
static
class
AnnotatedParameterizedTypeImpl
extends
AnnotatedTypeBaseImpl
implements
AnnotatedParameterizedType
{
AnnotatedParameterizedTypeImpl
(
ParameterizedType
type
,
LocationInfo
location
,
TypeAnnotation
[]
actualTypeAnnotations
,
TypeAnnotation
[]
allOnSameTargetTypeAnnotations
,
AnnotatedElement
decl
)
{
super
(
type
,
location
,
actualTypeAnnotations
,
allOnSameTargetTypeAnnotations
,
decl
);
}
@Override
public
AnnotatedType
[]
getAnnotatedActualTypeArguments
()
{
Type
[]
arguments
=
getParameterizedType
().
getActualTypeArguments
();
AnnotatedType
[]
res
=
new
AnnotatedType
[
arguments
.
length
];
Arrays
.
fill
(
res
,
EMPTY_ANNOTATED_TYPE
);
int
initialCapacity
=
getTypeAnnotations
().
length
;
for
(
int
i
=
0
;
i
<
res
.
length
;
i
++)
{
List
<
TypeAnnotation
>
l
=
new
ArrayList
<>(
initialCapacity
);
LocationInfo
newLoc
=
getLocation
().
pushTypeArg
((
byte
)
i
);
for
(
TypeAnnotation
t
:
getTypeAnnotations
())
if
(
t
.
getLocationInfo
().
isSameLocationInfo
(
newLoc
))
l
.
add
(
t
);
res
[
i
]
=
buildAnnotatedType
(
arguments
[
i
],
newLoc
,
l
.
toArray
(
new
TypeAnnotation
[
0
]),
getTypeAnnotations
(),
getDecl
());
}
return
res
;
}
private
ParameterizedType
getParameterizedType
()
{
return
(
ParameterizedType
)
getType
();
}
}
private
static
class
AnnotatedWildcardTypeImpl
extends
AnnotatedTypeBaseImpl
implements
AnnotatedWildcardType
{
private
final
boolean
hasUpperBounds
;
AnnotatedWildcardTypeImpl
(
WildcardType
type
,
LocationInfo
location
,
TypeAnnotation
[]
actualTypeAnnotations
,
TypeAnnotation
[]
allOnSameTargetTypeAnnotations
,
AnnotatedElement
decl
)
{
super
(
type
,
location
,
actualTypeAnnotations
,
allOnSameTargetTypeAnnotations
,
decl
);
hasUpperBounds
=
(
type
.
getLowerBounds
().
length
==
0
);
}
@Override
public
AnnotatedType
[]
getAnnotatedUpperBounds
()
{
if
(!
hasUpperBounds
())
return
new
AnnotatedType
[
0
];
return
getAnnotatedBounds
(
getWildcardType
().
getUpperBounds
());
}
@Override
public
AnnotatedType
[]
getAnnotatedLowerBounds
()
{
if
(
hasUpperBounds
)
return
new
AnnotatedType
[
0
];
return
getAnnotatedBounds
(
getWildcardType
().
getLowerBounds
());
}
private
AnnotatedType
[]
getAnnotatedBounds
(
Type
[]
bounds
)
{
AnnotatedType
[]
res
=
new
AnnotatedType
[
bounds
.
length
];
Arrays
.
fill
(
res
,
EMPTY_ANNOTATED_TYPE
);
LocationInfo
newLoc
=
getLocation
().
pushWildcard
();
int
initialCapacity
=
getTypeAnnotations
().
length
;
for
(
int
i
=
0
;
i
<
res
.
length
;
i
++)
{
List
<
TypeAnnotation
>
l
=
new
ArrayList
<>(
initialCapacity
);
for
(
TypeAnnotation
t
:
getTypeAnnotations
())
if
(
t
.
getLocationInfo
().
isSameLocationInfo
(
newLoc
))
l
.
add
(
t
);
res
[
i
]
=
buildAnnotatedType
(
bounds
[
i
],
newLoc
,
l
.
toArray
(
new
TypeAnnotation
[
0
]),
getTypeAnnotations
(),
getDecl
());
}
return
res
;
}
private
WildcardType
getWildcardType
()
{
return
(
WildcardType
)
getType
();
}
private
boolean
hasUpperBounds
()
{
return
hasUpperBounds
;
}
}
}
src/share/classes/sun/reflect/annotation/AnnotationParser.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -188,7 +188,7 @@ public class AnnotationParser {
...
@@ -188,7 +188,7 @@ public class AnnotationParser {
* available at runtime
* available at runtime
*/
*/
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
private
static
Annotation
parseAnnotation
(
ByteBuffer
buf
,
static
Annotation
parseAnnotation
(
ByteBuffer
buf
,
ConstantPool
constPool
,
ConstantPool
constPool
,
Class
<?>
container
,
Class
<?>
container
,
boolean
exceptionOnMissingAnnotationClass
)
{
boolean
exceptionOnMissingAnnotationClass
)
{
...
...
src/share/classes/sun/reflect/annotation/TypeAnnotation.java
0 → 100644
浏览文件 @
6f3e485f
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
sun.reflect.annotation
;
import
java.lang.annotation.Annotation
;
import
java.lang.annotation.AnnotationFormatError
;
import
java.lang.reflect.AnnotatedElement
;
import
java.nio.ByteBuffer
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* A TypeAnnotation contains all the information needed to transform type
* annotations on declarations in the class file to actual Annotations in
* AnnotatedType instances.
*
* TypeAnnotaions contain a base Annotation, location info (which lets you
* distinguish between '@A Inner.@B Outer' in for example nested types),
* target info and the declaration the TypeAnnotaiton was parsed from.
*/
public
class
TypeAnnotation
{
private
final
TypeAnnotationTargetInfo
targetInfo
;
private
final
LocationInfo
loc
;
private
final
Annotation
annotation
;
private
final
AnnotatedElement
baseDeclaration
;
public
TypeAnnotation
(
TypeAnnotationTargetInfo
targetInfo
,
LocationInfo
loc
,
Annotation
annotation
,
AnnotatedElement
baseDeclaration
)
{
this
.
targetInfo
=
targetInfo
;
this
.
loc
=
loc
;
this
.
annotation
=
annotation
;
this
.
baseDeclaration
=
baseDeclaration
;
}
public
TypeAnnotationTargetInfo
getTargetInfo
()
{
return
targetInfo
;
}
public
Annotation
getAnnotation
()
{
return
annotation
;
}
public
AnnotatedElement
getBaseDeclaration
()
{
return
baseDeclaration
;
}
public
LocationInfo
getLocationInfo
()
{
return
loc
;
}
public
static
List
<
TypeAnnotation
>
filter
(
TypeAnnotation
[]
typeAnnotations
,
TypeAnnotationTarget
predicate
)
{
ArrayList
<
TypeAnnotation
>
typeAnnos
=
new
ArrayList
<>(
typeAnnotations
.
length
);
for
(
TypeAnnotation
t
:
typeAnnotations
)
if
(
t
.
getTargetInfo
().
getTarget
()
==
predicate
)
typeAnnos
.
add
(
t
);
typeAnnos
.
trimToSize
();
return
typeAnnos
;
}
public
static
enum
TypeAnnotationTarget
{
CLASS_TYPE_PARAMETER
,
METHOD_TYPE_PARAMETER
,
CLASS_EXTENDS
,
CLASS_IMPLEMENTS
,
CLASS_PARAMETER_BOUND
,
METHOD_PARAMETER_BOUND
,
METHOD_RETURN_TYPE
,
METHOD_RECEIVER_TYPE
,
FIELD_TYPE
,
THROWS
;
}
public
static
class
TypeAnnotationTargetInfo
{
private
final
TypeAnnotationTarget
target
;
private
final
int
count
;
private
final
int
secondaryIndex
;
private
static
final
int
UNUSED_INDEX
=
-
2
;
// this is not a valid index in the 308 spec
public
TypeAnnotationTargetInfo
(
TypeAnnotationTarget
target
)
{
this
(
target
,
UNUSED_INDEX
,
UNUSED_INDEX
);
}
public
TypeAnnotationTargetInfo
(
TypeAnnotationTarget
target
,
int
count
)
{
this
(
target
,
count
,
UNUSED_INDEX
);
}
public
TypeAnnotationTargetInfo
(
TypeAnnotationTarget
target
,
int
count
,
int
secondaryIndex
)
{
this
.
target
=
target
;
this
.
count
=
count
;
this
.
secondaryIndex
=
secondaryIndex
;
}
public
TypeAnnotationTarget
getTarget
()
{
return
target
;
}
public
int
getCount
()
{
return
count
;
}
public
int
getSecondaryIndex
()
{
return
secondaryIndex
;
}
@Override
public
String
toString
()
{
return
""
+
target
+
": "
+
count
+
", "
+
secondaryIndex
;
}
}
public
static
class
LocationInfo
{
private
final
int
depth
;
private
final
Location
[]
locations
;
private
LocationInfo
()
{
this
(
0
,
new
Location
[
0
]);
}
private
LocationInfo
(
int
depth
,
Location
[]
locations
)
{
this
.
depth
=
depth
;
this
.
locations
=
locations
;
}
public
static
final
LocationInfo
BASE_LOCATION
=
new
LocationInfo
();
public
static
LocationInfo
parseLocationInfo
(
ByteBuffer
buf
)
{
int
depth
=
buf
.
get
();
if
(
depth
==
0
)
return
BASE_LOCATION
;
Location
[]
locations
=
new
Location
[
depth
];
for
(
int
i
=
0
;
i
<
depth
;
i
++)
{
byte
tag
=
buf
.
get
();
byte
index
=
buf
.
get
();
if
(!(
tag
==
0
||
tag
==
1
|
tag
==
2
||
tag
==
3
))
throw
new
AnnotationFormatError
(
"Bad Location encoding in Type Annotation"
);
if
(
tag
!=
3
&&
index
!=
0
)
throw
new
AnnotationFormatError
(
"Bad Location encoding in Type Annotation"
);
locations
[
i
]
=
new
Location
(
tag
,
index
);
}
return
new
LocationInfo
(
depth
,
locations
);
}
public
LocationInfo
pushArray
()
{
return
pushLocation
((
byte
)
0
,
(
byte
)
0
);
}
public
LocationInfo
pushInner
()
{
return
pushLocation
((
byte
)
1
,
(
byte
)
0
);
}
public
LocationInfo
pushWildcard
()
{
return
pushLocation
((
byte
)
2
,
(
byte
)
0
);
}
public
LocationInfo
pushTypeArg
(
byte
index
)
{
return
pushLocation
((
byte
)
3
,
index
);
}
public
LocationInfo
pushLocation
(
byte
tag
,
byte
index
)
{
int
newDepth
=
this
.
depth
+
1
;
Location
[]
res
=
new
Location
[
newDepth
];
System
.
arraycopy
(
this
.
locations
,
0
,
res
,
0
,
depth
);
res
[
newDepth
-
1
]
=
new
Location
(
tag
,
index
);
return
new
LocationInfo
(
newDepth
,
res
);
}
public
TypeAnnotation
[]
filter
(
TypeAnnotation
[]
ta
)
{
ArrayList
<
TypeAnnotation
>
l
=
new
ArrayList
<>(
ta
.
length
);
for
(
TypeAnnotation
t
:
ta
)
{
if
(
isSameLocationInfo
(
t
.
getLocationInfo
()))
l
.
add
(
t
);
}
return
l
.
toArray
(
new
TypeAnnotation
[
0
]);
}
boolean
isSameLocationInfo
(
LocationInfo
other
)
{
if
(
depth
!=
other
.
depth
)
return
false
;
for
(
int
i
=
0
;
i
<
depth
;
i
++)
if
(!
locations
[
i
].
isSameLocation
(
other
.
locations
[
i
]))
return
false
;
return
true
;
}
public
static
class
Location
{
public
final
byte
tag
;
public
final
byte
index
;
boolean
isSameLocation
(
Location
other
)
{
return
tag
==
other
.
tag
&&
index
==
other
.
index
;
}
public
Location
(
byte
tag
,
byte
index
)
{
this
.
tag
=
tag
;
this
.
index
=
index
;
}
}
}
@Override
public
String
toString
()
{
return
annotation
.
toString
()
+
" with Targetnfo: "
+
targetInfo
.
toString
()
+
" on base declaration: "
+
baseDeclaration
.
toString
();
}
}
src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
0 → 100644
浏览文件 @
6f3e485f
此差异已折叠。
点击以展开。
src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -25,13 +25,18 @@
...
@@ -25,13 +25,18 @@
package
sun.reflect.generics.reflectiveObjects
;
package
sun.reflect.generics.reflectiveObjects
;
import
java.lang.annotation.Annotation
;
import
java.lang.annotation.*
;
import
java.lang.reflect.AnnotatedType
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.GenericDeclaration
;
import
java.lang.reflect.GenericDeclaration
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.TypeVariable
;
import
java.lang.reflect.TypeVariable
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Objects
;
import
sun.reflect.annotation.AnnotationSupport
;
import
sun.reflect.annotation.TypeAnnotationParser
;
import
sun.reflect.annotation.AnnotationType
;
import
sun.reflect.generics.factory.GenericsFactory
;
import
sun.reflect.generics.factory.GenericsFactory
;
import
sun.reflect.generics.tree.FieldTypeSignature
;
import
sun.reflect.generics.tree.FieldTypeSignature
;
import
sun.reflect.generics.visitor.Reifier
;
import
sun.reflect.generics.visitor.Reifier
;
...
@@ -182,45 +187,75 @@ public class TypeVariableImpl<D extends GenericDeclaration>
...
@@ -182,45 +187,75 @@ public class TypeVariableImpl<D extends GenericDeclaration>
return
genericDeclaration
.
hashCode
()
^
name
.
hashCode
();
return
genericDeclaration
.
hashCode
()
^
name
.
hashCode
();
}
}
//
Currently vacuous i
mplementations of AnnotatedElement methods.
//
I
mplementations of AnnotatedElement methods.
public
boolean
isAnnotationPresent
(
Class
<?
extends
Annotation
>
annotationClass
)
{
public
boolean
isAnnotationPresent
(
Class
<?
extends
Annotation
>
annotationClass
)
{
Objects
.
requireNonNull
(
annotationClass
);
Objects
.
requireNonNull
(
annotationClass
);
return
false
;
return
false
;
}
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
extends
Annotation
>
T
getAnnotation
(
Class
<
T
>
annotationClass
)
{
public
<
T
extends
Annotation
>
T
getAnnotation
(
Class
<
T
>
annotationClass
)
{
Objects
.
requireNonNull
(
annotationClass
);
Objects
.
requireNonNull
(
annotationClass
);
return
null
;
// T is an Annotation type, the return value of get will be an annotation
return
(
T
)
mapAnnotations
(
getAnnotations
()).
get
(
annotationClass
);
}
}
public
<
T
extends
Annotation
>
T
getDeclaredAnnotation
(
Class
<
T
>
annotationClass
)
{
public
<
T
extends
Annotation
>
T
getDeclaredAnnotation
(
Class
<
T
>
annotationClass
)
{
Objects
.
requireNonNull
(
annotationClass
);
Objects
.
requireNonNull
(
annotationClass
);
return
null
;
return
getAnnotation
(
annotationClass
)
;
}
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
extends
Annotation
>
T
[]
getAnnotations
(
Class
<
T
>
annotationClass
)
{
public
<
T
extends
Annotation
>
T
[]
getAnnotations
(
Class
<
T
>
annotationClass
)
{
Objects
.
requireNonNull
(
annotationClass
);
Objects
.
requireNonNull
(
annotationClass
);
// safe because annotationClass is the class for T
return
AnnotationSupport
.
getMultipleAnnotations
(
mapAnnotations
(
getAnnotations
()),
annotationClass
);
return
(
T
[])
Array
.
newInstance
(
annotationClass
,
0
);
}
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
extends
Annotation
>
T
[]
getDeclaredAnnotations
(
Class
<
T
>
annotationClass
)
{
public
<
T
extends
Annotation
>
T
[]
getDeclaredAnnotations
(
Class
<
T
>
annotationClass
)
{
Objects
.
requireNonNull
(
annotationClass
);
Objects
.
requireNonNull
(
annotationClass
);
// safe because annotationClass is the class for T
return
getAnnotations
(
annotationClass
);
return
(
T
[])
Array
.
newInstance
(
annotationClass
,
0
);
}
}
public
Annotation
[]
getAnnotations
()
{
public
Annotation
[]
getAnnotations
()
{
// Since zero-length, don't need defensive clone
int
myIndex
=
typeVarIndex
();
return
EMPTY_ANNOTATION_ARRAY
;
if
(
myIndex
<
0
)
throw
new
AssertionError
(
"Index must be non-negative."
);
return
TypeAnnotationParser
.
parseTypeVariableAnnotations
(
getGenericDeclaration
(),
myIndex
);
}
}
public
Annotation
[]
getDeclaredAnnotations
()
{
public
Annotation
[]
getDeclaredAnnotations
()
{
// Since zero-length, don't need defensive clone
return
getAnnotations
();
return
EMPTY_ANNOTATION_ARRAY
;
}
public
AnnotatedType
[]
getAnnotatedBounds
()
{
return
TypeAnnotationParser
.
parseAnnotatedBounds
(
getBounds
(),
getGenericDeclaration
(),
typeVarIndex
());
}
}
private
static
final
Annotation
[]
EMPTY_ANNOTATION_ARRAY
=
new
Annotation
[
0
];
private
static
final
Annotation
[]
EMPTY_ANNOTATION_ARRAY
=
new
Annotation
[
0
];
// Helpers for annotation methods
private
int
typeVarIndex
()
{
TypeVariable
<?>[]
tVars
=
getGenericDeclaration
().
getTypeParameters
();
int
i
=
-
1
;
for
(
TypeVariable
<?>
v
:
tVars
)
{
i
++;
if
(
equals
(
v
))
return
i
;
}
return
-
1
;
}
private
static
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
mapAnnotations
(
Annotation
[]
annos
)
{
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
result
=
new
LinkedHashMap
<>();
for
(
Annotation
a
:
annos
)
{
Class
<?
extends
Annotation
>
klass
=
a
.
annotationType
();
AnnotationType
type
=
AnnotationType
.
getInstance
(
klass
);
if
(
type
.
retention
()
==
RetentionPolicy
.
RUNTIME
)
if
(
result
.
put
(
klass
,
a
)
!=
null
)
throw
new
AnnotationFormatError
(
"Duplicate annotation for class: "
+
klass
+
": "
+
a
);
}
return
result
;
}
}
}
src/share/javavm/export/jvm.h
浏览文件 @
6f3e485f
...
@@ -465,6 +465,12 @@ JVM_GetClassSignature(JNIEnv *env, jclass cls);
...
@@ -465,6 +465,12 @@ JVM_GetClassSignature(JNIEnv *env, jclass cls);
JNIEXPORT
jbyteArray
JNICALL
JNIEXPORT
jbyteArray
JNICALL
JVM_GetClassAnnotations
(
JNIEnv
*
env
,
jclass
cls
);
JVM_GetClassAnnotations
(
JNIEnv
*
env
,
jclass
cls
);
/* Type use annotations support (JDK 1.8) */
JNIEXPORT
jbyteArray
JNICALL
JVM_GetClassTypeAnnotations
(
JNIEnv
*
env
,
jclass
cls
);
/*
/*
* New (JDK 1.4) reflection implementation
* New (JDK 1.4) reflection implementation
*/
*/
...
...
src/share/native/java/lang/Class.c
浏览文件 @
6f3e485f
/*
/*
* Copyright (c) 1994, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -75,7 +75,8 @@ static JNINativeMethod methods[] = {
...
@@ -75,7 +75,8 @@ static JNINativeMethod methods[] = {
{
"getRawAnnotations"
,
"()"
BA
,
(
void
*
)
&
JVM_GetClassAnnotations
},
{
"getRawAnnotations"
,
"()"
BA
,
(
void
*
)
&
JVM_GetClassAnnotations
},
{
"getConstantPool"
,
"()"
CPL
,
(
void
*
)
&
JVM_GetClassConstantPool
},
{
"getConstantPool"
,
"()"
CPL
,
(
void
*
)
&
JVM_GetClassConstantPool
},
{
"desiredAssertionStatus0"
,
"("
CLS
")Z"
,(
void
*
)
&
JVM_DesiredAssertionStatus
},
{
"desiredAssertionStatus0"
,
"("
CLS
")Z"
,(
void
*
)
&
JVM_DesiredAssertionStatus
},
{
"getEnclosingMethod0"
,
"()["
OBJ
,
(
void
*
)
&
JVM_GetEnclosingMethodInfo
}
{
"getEnclosingMethod0"
,
"()["
OBJ
,
(
void
*
)
&
JVM_GetEnclosingMethodInfo
},
{
"getRawTypeAnnotations"
,
"()"
BA
,
(
void
*
)
&
JVM_GetClassTypeAnnotations
},
};
};
#undef OBJ
#undef OBJ
...
...
test/java/lang/annotation/TypeAnnotationReflection.java
0 → 100644
浏览文件 @
6f3e485f
/*
* 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 8004698
* @summary Unit test for type annotations
*/
import
java.util.*
;
import
java.lang.annotation.*
;
import
java.lang.reflect.*
;
import
java.io.Serializable
;
public
class
TypeAnnotationReflection
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
testSuper
();
testInterfaces
();
testReturnType
();
testNested
();
testArray
();
testRunException
();
testClassTypeVarBounds
();
testMethodTypeVarBounds
();
testFields
();
testClassTypeVar
();
testMethodTypeVar
();
testParameterizedType
();
testNestedParameterizedType
();
testWildcardType
();
}
private
static
void
check
(
boolean
b
)
{
if
(!
b
)
throw
new
RuntimeException
();
}
private
static
void
testSuper
()
throws
Exception
{
check
(
Object
.
class
.
getAnnotatedSuperclass
().
getAnnotations
().
length
==
0
);
check
(
Class
.
class
.
getAnnotatedSuperclass
().
getAnnotations
().
length
==
0
);
AnnotatedType
a
;
a
=
TestClassArray
.
class
.
getAnnotatedSuperclass
();
Annotation
[]
annos
=
a
.
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"extends"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"extends2"
));
}
private
static
void
testInterfaces
()
throws
Exception
{
AnnotatedType
[]
as
;
as
=
TestClassArray
.
class
.
getAnnotatedInterfaces
();
check
(
as
.
length
==
3
);
check
(
as
[
1
].
getAnnotations
().
length
==
0
);
Annotation
[]
annos
;
annos
=
as
[
0
].
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"implements serializable"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"implements2 serializable"
));
annos
=
as
[
2
].
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"implements cloneable"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"implements2 cloneable"
));
}
private
static
void
testReturnType
()
throws
Exception
{
Method
m
=
TestClassArray
.
class
.
getDeclaredMethod
(
"foo"
,
(
Class
<?>[])
null
);
Annotation
[]
annos
=
m
.
getAnnotatedReturnType
().
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"return1"
));
}
private
static
void
testNested
()
throws
Exception
{
Method
m
=
TestClassNested
.
class
.
getDeclaredMethod
(
"foo"
,
(
Class
<?>[])
null
);
Annotation
[]
annos
=
m
.
getAnnotatedReturnType
().
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"array"
));
AnnotatedType
t
=
m
.
getAnnotatedReturnType
();
t
=
((
AnnotatedArrayType
)
t
).
getAnnotatedGenericComponentType
();
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"Inner"
));
}
private
static
void
testArray
()
throws
Exception
{
Method
m
=
TestClassArray
.
class
.
getDeclaredMethod
(
"foo"
,
(
Class
<?>[])
null
);
AnnotatedArrayType
t
=
(
AnnotatedArrayType
)
m
.
getAnnotatedReturnType
();
Annotation
[]
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"return1"
));
t
=
(
AnnotatedArrayType
)
t
.
getAnnotatedGenericComponentType
();
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
0
);
t
=
(
AnnotatedArrayType
)
t
.
getAnnotatedGenericComponentType
();
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"return3"
));
AnnotatedType
tt
=
t
.
getAnnotatedGenericComponentType
();
check
(!(
tt
instanceof
AnnotatedArrayType
));
annos
=
tt
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"return4"
));
}
private
static
void
testRunException
()
throws
Exception
{
Method
m
=
TestClassException
.
class
.
getDeclaredMethod
(
"foo"
,
(
Class
<?>[])
null
);
AnnotatedType
[]
ts
=
m
.
getAnnotatedExceptionTypes
();
check
(
ts
.
length
==
3
);
AnnotatedType
t
;
Annotation
[]
annos
;
t
=
ts
[
0
];
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"RE"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"RE2"
));
t
=
ts
[
1
];
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
0
);
t
=
ts
[
2
];
annos
=
t
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"AIOOBE"
));
}
private
static
void
testClassTypeVarBounds
()
throws
Exception
{
Method
m
=
TestClassTypeVarAndField
.
class
.
getDeclaredMethod
(
"foo"
,
(
Class
<?>[])
null
);
AnnotatedType
ret
=
m
.
getAnnotatedReturnType
();
Annotation
[]
annos
=
ret
.
getAnnotations
();
check
(
annos
.
length
==
2
);
AnnotatedType
[]
annotatedBounds
=
((
AnnotatedTypeVariable
)
ret
).
getAnnotatedBounds
();
check
(
annotatedBounds
.
length
==
2
);
annos
=
annotatedBounds
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"Object1"
));
annos
=
annotatedBounds
[
1
].
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"Runnable1"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"Runnable2"
));
}
private
static
void
testMethodTypeVarBounds
()
throws
Exception
{
Method
m2
=
TestClassTypeVarAndField
.
class
.
getDeclaredMethod
(
"foo2"
,
(
Class
<?>[])
null
);
AnnotatedType
ret2
=
m2
.
getAnnotatedReturnType
();
AnnotatedType
[]
annotatedBounds2
=
((
AnnotatedTypeVariable
)
ret2
).
getAnnotatedBounds
();
check
(
annotatedBounds2
.
length
==
1
);
Annotation
[]
annos
=
annotatedBounds2
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"M Runnable"
));
}
private
static
void
testFields
()
throws
Exception
{
Field
f1
=
TestClassTypeVarAndField
.
class
.
getDeclaredField
(
"field1"
);
AnnotatedType
at
;
Annotation
[]
annos
;
at
=
f1
.
getAnnotatedType
();
annos
=
at
.
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"T1 field"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"T2 field"
));
Field
f2
=
TestClassTypeVarAndField
.
class
.
getDeclaredField
(
"field2"
);
at
=
f2
.
getAnnotatedType
();
annos
=
at
.
getAnnotations
();
check
(
annos
.
length
==
0
);
Field
f3
=
TestClassTypeVarAndField
.
class
.
getDeclaredField
(
"field3"
);
at
=
f3
.
getAnnotatedType
();
annos
=
at
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"Object field"
));
}
private
static
void
testClassTypeVar
()
throws
Exception
{
TypeVariable
[]
typeVars
=
TestClassTypeVarAndField
.
class
.
getTypeParameters
();
Annotation
[]
annos
;
check
(
typeVars
.
length
==
2
);
// First TypeVar
AnnotatedType
[]
annotatedBounds
=
typeVars
[
0
].
getAnnotatedBounds
();
check
(
annotatedBounds
.
length
==
2
);
annos
=
annotatedBounds
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"Object1"
));
annos
=
annotatedBounds
[
1
].
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(
annos
[
1
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"Runnable1"
));
check
(((
TypeAnno2
)
annos
[
1
]).
value
().
equals
(
"Runnable2"
));
// second TypeVar regular anno
Annotation
[]
regularAnnos
=
typeVars
[
1
].
getAnnotations
();
check
(
regularAnnos
.
length
==
1
);
check
(
typeVars
[
1
].
getAnnotation
(
TypeAnno
.
class
).
value
().
equals
(
"EE"
));
// second TypeVar
annotatedBounds
=
typeVars
[
1
].
getAnnotatedBounds
();
check
(
annotatedBounds
.
length
==
1
);
annos
=
annotatedBounds
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno2
.
class
));
check
(((
TypeAnno2
)
annos
[
0
]).
value
().
equals
(
"EEBound"
));
}
private
static
void
testMethodTypeVar
()
throws
Exception
{
Method
m2
=
TestClassTypeVarAndField
.
class
.
getDeclaredMethod
(
"foo2"
,
(
Class
<?>[])
null
);
TypeVariable
[]
t
=
m2
.
getTypeParameters
();
check
(
t
.
length
==
1
);
Annotation
[]
annos
=
t
[
0
].
getAnnotations
();
check
(
annos
.
length
==
0
);
AnnotatedType
[]
annotatedBounds2
=
t
[
0
].
getAnnotatedBounds
();
check
(
annotatedBounds2
.
length
==
1
);
annos
=
annotatedBounds2
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"M Runnable"
));
// Second method
m2
=
TestClassTypeVarAndField
.
class
.
getDeclaredMethod
(
"foo3"
,
(
Class
<?>[])
null
);
t
=
m2
.
getTypeParameters
();
check
(
t
.
length
==
1
);
annos
=
t
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
annos
[
0
].
annotationType
().
equals
(
TypeAnno
.
class
));
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"K"
));
annotatedBounds2
=
t
[
0
].
getAnnotatedBounds
();
check
(
annotatedBounds2
.
length
==
1
);
annos
=
annotatedBounds2
[
0
].
getAnnotations
();
check
(
annos
.
length
==
0
);
}
private
static
void
testParameterizedType
()
{
// Base
AnnotatedType
[]
as
;
as
=
TestParameterizedType
.
class
.
getAnnotatedInterfaces
();
check
(
as
.
length
==
1
);
check
(
as
[
0
].
getAnnotations
().
length
==
1
);
check
(
as
[
0
].
getAnnotation
(
TypeAnno
.
class
).
value
().
equals
(
"M"
));
Annotation
[]
annos
;
as
=
((
AnnotatedParameterizedType
)
as
[
0
]).
getAnnotatedActualTypeArguments
();
check
(
as
.
length
==
2
);
annos
=
as
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(
as
[
0
].
getAnnotation
(
TypeAnno
.
class
).
value
().
equals
(
"S"
));
check
(
as
[
0
].
getAnnotation
(
TypeAnno2
.
class
)
==
null
);
annos
=
as
[
1
].
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"I"
));
check
(
as
[
1
].
getAnnotation
(
TypeAnno2
.
class
).
value
().
equals
(
"I2"
));
}
private
static
void
testNestedParameterizedType
()
throws
Exception
{
Method
m
=
TestParameterizedType
.
class
.
getDeclaredMethod
(
"foo2"
,
(
Class
<?>[])
null
);
AnnotatedType
ret
=
m
.
getAnnotatedReturnType
();
Annotation
[]
annos
;
annos
=
ret
.
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"I"
));
AnnotatedType
[]
args
=
((
AnnotatedParameterizedType
)
ret
).
getAnnotatedActualTypeArguments
();
check
(
args
.
length
==
1
);
annos
=
args
[
0
].
getAnnotations
();
check
(
annos
.
length
==
2
);
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"I1"
));
check
(
args
[
0
].
getAnnotation
(
TypeAnno2
.
class
).
value
().
equals
(
"I2"
));
}
private
static
void
testWildcardType
()
throws
Exception
{
Method
m
=
TestWildcardType
.
class
.
getDeclaredMethod
(
"foo"
,
(
Class
<?>[])
null
);
AnnotatedType
ret
=
m
.
getAnnotatedReturnType
();
AnnotatedType
[]
t
;
t
=
((
AnnotatedParameterizedType
)
ret
).
getAnnotatedActualTypeArguments
();
check
(
t
.
length
==
1
);
ret
=
t
[
0
];
Field
f
=
TestWildcardType
.
class
.
getDeclaredField
(
"f1"
);
AnnotatedWildcardType
w
=
(
AnnotatedWildcardType
)((
AnnotatedParameterizedType
)
f
.
getAnnotatedType
()).
getAnnotatedActualTypeArguments
()[
0
];
t
=
w
.
getAnnotatedLowerBounds
();
check
(
t
.
length
==
0
);
t
=
w
.
getAnnotatedUpperBounds
();
check
(
t
.
length
==
1
);
Annotation
[]
annos
;
annos
=
t
[
0
].
getAnnotations
();
check
(
annos
.
length
==
1
);
check
(((
TypeAnno
)
annos
[
0
]).
value
().
equals
(
"2"
));
f
=
TestWildcardType
.
class
.
getDeclaredField
(
"f2"
);
w
=
(
AnnotatedWildcardType
)((
AnnotatedParameterizedType
)
f
.
getAnnotatedType
()).
getAnnotatedActualTypeArguments
()[
0
];
t
=
w
.
getAnnotatedUpperBounds
();
check
(
t
.
length
==
0
);
t
=
w
.
getAnnotatedLowerBounds
();
check
(
t
.
length
==
1
);
}
}
abstract
class
TestWildcardType
{
public
<
T
>
List
<?
super
T
>
foo
()
{
return
null
;}
public
Class
<
@TypeAnno
(
"1"
)
?
extends
@TypeAnno
(
"2"
)
Annotation
>
f1
;
public
Class
<
@TypeAnno
(
"3"
)
?
super
@TypeAnno
(
"4"
)
Annotation
>
f2
;
}
abstract
class
TestParameterizedType
implements
@TypeAnno
(
"M"
)
Map
<
@TypeAnno
(
"S"
)
String
,
@TypeAnno
(
"I"
)
@TypeAnno2
(
"I2"
)
Integer
>
{
public
ParameterizedOuter
<
String
>.
ParameterizedInner
<
Integer
>
foo
()
{
return
null
;}
public
@TypeAnno
(
"O"
)
ParameterizedOuter
<
@TypeAnno
(
"S1"
)
@TypeAnno2
(
"S2"
)
String
>.
@TypeAnno
(
"I"
)
ParameterizedInner
<
@TypeAnno
(
"I1"
)
@TypeAnno2
(
"I2"
)
Integer
>
foo2
()
{
return
null
;
}
}
class
ParameterizedOuter
<
T
>
{
class
ParameterizedInner
<
U
>
{}
}
abstract
class
TestClassArray
extends
@TypeAnno
(
"extends"
)
@TypeAnno2
(
"extends2"
)
Object
implements
@TypeAnno
(
"implements serializable"
)
@TypeAnno2
(
"implements2 serializable"
)
Serializable
,
Readable
,
@TypeAnno
(
"implements cloneable"
)
@TypeAnno2
(
"implements2 cloneable"
)
Cloneable
{
public
@TypeAnno
(
"return4"
)
Object
@TypeAnno
(
"return1"
)
[][]
@TypeAnno
(
"return3"
)[]
foo
()
{
return
null
;
}
}
abstract
class
TestClassNested
{
public
@TypeAnno
(
"Outer"
)
Outer
.
@TypeAnno
(
"Inner"
)
Inner
@TypeAnno
(
"array"
)[]
foo
()
{
return
null
;
}
}
class
Outer
{
class
Inner
{
}
}
abstract
class
TestClassException
{
public
Object
foo
()
throws
@TypeAnno
(
"RE"
)
@TypeAnno2
(
"RE2"
)
RuntimeException
,
NullPointerException
,
@TypeAnno
(
"AIOOBE"
)
ArrayIndexOutOfBoundsException
{
return
null
;
}
}
abstract
class
TestClassTypeVarAndField
<
T
extends
@TypeAnno
(
"Object1"
)
Object
&
@TypeAnno
(
"Runnable1"
)
@TypeAnno2
(
"Runnable2"
)
Runnable
,
@TypeAnno
(
"EE"
)
EE
extends
@TypeAnno2
(
"EEBound"
)
Runnable
>
{
@TypeAnno
(
"T1 field"
)
@TypeAnno2
(
"T2 field"
)
T
field1
;
T
field2
;
@TypeAnno
(
"Object field"
)
Object
field3
;
public
@TypeAnno
(
"t1"
)
@TypeAnno2
(
"t2"
)
T
foo
(){
return
null
;
}
public
<
M
extends
@TypeAnno
(
"M Runnable"
)
Runnable
>
M
foo2
()
{
return
null
;}
public
<
@TypeAnno
(
"K"
)
K
extends
Cloneable
>
K
foo3
()
{
return
null
;}
}
@Target
(
ElementType
.
TYPE_USE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
TypeAnno
{
String
value
();
}
@Target
(
ElementType
.
TYPE_USE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
TypeAnno2
{
String
value
();
}
test/java/lang/annotation/TypeParamAnnotation.java
0 → 100644
浏览文件 @
6f3e485f
/*
* 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 8004698
* @summary Unit test for annotations on TypeVariables
*/
import
java.util.*
;
import
java.lang.annotation.*
;
import
java.lang.reflect.*
;
import
java.io.Serializable
;
public
class
TypeParamAnnotation
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
testOnClass
();
testOnMethod
();
testGetAnno
();
testGetAnnos
();
}
private
static
void
check
(
boolean
b
)
{
if
(!
b
)
throw
new
RuntimeException
();
}
private
static
void
testOnClass
()
{
TypeVariable
<?>[]
ts
=
TypeParam
.
class
.
getTypeParameters
();
check
(
ts
.
length
==
3
);
Annotation
[]
as
;
as
=
ts
[
0
].
getAnnotations
();
check
(
as
.
length
==
2
);
check
(((
ParamAnno
)
as
[
0
]).
value
().
equals
(
"t"
));
check
(((
ParamAnno2
)
as
[
1
]).
value
()
==
1
);
as
=
ts
[
1
].
getAnnotations
();
check
(
as
.
length
==
0
);
as
=
ts
[
2
].
getAnnotations
();
check
(
as
.
length
==
2
);
check
(((
ParamAnno
)
as
[
0
]).
value
().
equals
(
"v"
));
check
(((
ParamAnno2
)
as
[
1
]).
value
()
==
2
);
}
private
static
void
testOnMethod
()
throws
Exception
{
TypeVariable
<?>[]
ts
=
TypeParam
.
class
.
getDeclaredMethod
(
"foo"
).
getTypeParameters
();
check
(
ts
.
length
==
3
);
Annotation
[]
as
;
as
=
ts
[
0
].
getAnnotations
();
check
(
as
.
length
==
2
);
check
(((
ParamAnno
)
as
[
0
]).
value
().
equals
(
"x"
));
check
(((
ParamAnno2
)
as
[
1
]).
value
()
==
3
);
as
=
ts
[
1
].
getAnnotations
();
check
(
as
.
length
==
0
);
as
=
ts
[
2
].
getAnnotations
();
check
(
as
.
length
==
2
);
check
(((
ParamAnno
)
as
[
0
]).
value
().
equals
(
"z"
));
check
(((
ParamAnno2
)
as
[
1
]).
value
()
==
4
);
}
private
static
void
testGetAnno
()
{
TypeVariable
<?>[]
ts
=
TypeParam
.
class
.
getTypeParameters
();
ParamAnno
a
;
a
=
ts
[
0
].
getAnnotation
(
ParamAnno
.
class
);
check
(
a
.
value
().
equals
(
"t"
));
}
private
static
void
testGetAnnos
()
throws
Exception
{
TypeVariable
<?>[]
ts
=
TypeParam
.
class
.
getDeclaredMethod
(
"foo"
).
getTypeParameters
();
ParamAnno2
[]
as
;
as
=
ts
[
0
].
getAnnotations
(
ParamAnno2
.
class
);
check
(
as
.
length
==
1
);
check
(
as
[
0
].
value
()
==
3
);
}
}
class
TypeParam
<
@ParamAnno
(
"t"
)
@ParamAnno2
(
1
)
T
,
U
,
@ParamAnno
(
"v"
)
@ParamAnno2
(
2
)
V
extends
Runnable
>
{
public
<
@ParamAnno
(
"x"
)
@ParamAnno2
(
3
)
X
,
Y
,
@ParamAnno
(
"z"
)
@ParamAnno2
(
4
)
Z
extends
Cloneable
>
void
foo
()
{}
}
@Target
(
ElementType
.
TYPE_PARAMETER
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
ParamAnno
{
String
value
();
}
@Target
(
ElementType
.
TYPE_PARAMETER
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
ParamAnno2
{
int
value
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录