src/share/classes/java/lang/reflect/Field.java
Print this page
rev 10466 : 8054987: (reflect) Add sharing of annotations between instances of Executable
Reviewed-by: duke
@@ -79,10 +79,13 @@
// Cached field accessor created with override
private FieldAccessor overrideFieldAccessor;
// For sharing of FieldAccessors. This branching structure is
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
+ //
+ // If this branching structure would ever contain cycles, deadlocks can
+ // occur in annotation code.
private Field root;
// Generics infrastructure
private String getGenericSignature() {return signature;}
@@ -139,10 +142,13 @@
// method in the VM. (All of this contortion is only necessary
// because of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
+ if (this.root != null)
+ throw new IllegalArgumentException("Can not copy a non-root Field");
+
Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
res.root = this;
// Might as well eagerly propagate this if already present
res.fieldAccessor = fieldAccessor;
res.overrideFieldAccessor = overrideFieldAccessor;
@@ -1135,15 +1141,20 @@
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
+ Field root = this.root;
+ if (root != null) {
+ declaredAnnotations = root.declaredAnnotations();
+ } else {
declaredAnnotations = AnnotationParser.parseAnnotations(
- annotations, sun.misc.SharedSecrets.getJavaLangAccess().
- getConstantPool(getDeclaringClass()),
+ annotations,
+ sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
+ }
return declaredAnnotations;
}
private native byte[] getTypeAnnotationBytes0();