src/share/classes/sun/reflect/annotation/AnnotationType.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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

@@ -23,10 +23,12 @@
  * questions.
  */
 
 package sun.reflect.annotation;
 
+import sun.misc.JavaLangAccess;
+
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;

@@ -43,47 +45,53 @@
      * Member name -> type mapping. Note that primitive types
      * are represented by the class objects for the corresponding wrapper
      * types.  This matches the return value that must be used for a
      * dynamic proxy, allowing for a simple isInstance test.
      */
-    private final Map<String, Class<?>> memberTypes = new HashMap<String,Class<?>>();
+    private final Map<String, Class<?>> memberTypes;
 
     /**
      * Member name -> default value mapping.
      */
-    private final Map<String, Object> memberDefaults =
-        new HashMap<String, Object>();
+    private final Map<String, Object> memberDefaults;
 
     /**
-     * Member name -> Method object mapping. This (and its assoicated
+     * Member name -> Method object mapping. This (and its associated
      * accessor) are used only to generate AnnotationTypeMismatchExceptions.
      */
-    private final Map<String, Method> members = new HashMap<String, Method>();
+    private final Map<String, Method> members;
 
     /**
      * The retention policy for this annotation type.
      */
-    private RetentionPolicy retention = RetentionPolicy.RUNTIME;;
+    private final RetentionPolicy retention;
 
     /**
      * Whether this annotation type is inherited.
      */
-    private boolean inherited = false;
+    private final boolean inherited;
 
     /**
      * Returns an AnnotationType instance for the specified annotation type.
      *
      * @throw IllegalArgumentException if the specified class object for
      *     does not represent a valid annotation type
      */
-    public static synchronized AnnotationType getInstance(
+    public static AnnotationType getInstance(
         Class<? extends Annotation> annotationClass)
     {
-        AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess().
-            getAnnotationType(annotationClass);
-        if (result == null)
-            result = new AnnotationType((Class<? extends Annotation>) annotationClass);
+        JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess();
+        AnnotationType result = jla.getAnnotationType(annotationClass); // volatile read
+        if (result == null) {
+            result = new AnnotationType(annotationClass);
+            // try to CAS the AnnotationType: null -> result
+            if (!jla.casAnnotationType(annotationClass, null, result)) {
+                // somebody was quicker -> read it's result
+                result = jla.getAnnotationType(annotationClass);
+                assert result != null;
+            }
+        }
 
         return result;
     }
 
     /**

@@ -103,10 +111,13 @@
                     // Initialize memberTypes and defaultValues
                     return annotationClass.getDeclaredMethods();
                 }
             });
 
+        memberTypes = new HashMap<String,Class<?>>(methods.length+1, 1.0f);
+        memberDefaults = new HashMap<String, Object>(0);
+        members = new HashMap<String, Method>(methods.length+1, 1.0f);
 
         for (Method method :  methods) {
             if (method.getParameterTypes().length != 0)
                 throw new IllegalArgumentException(method + " has params");
             String name = method.getName();

@@ -115,26 +126,33 @@
             members.put(name, method);
 
             Object defaultValue = method.getDefaultValue();
             if (defaultValue != null)
                 memberDefaults.put(name, defaultValue);
-
-            members.put(name, method);
         }
 
-        sun.misc.SharedSecrets.getJavaLangAccess().
-            setAnnotationType(annotationClass, this);
-
         // Initialize retention, & inherited fields.  Special treatment
         // of the corresponding annotation types breaks infinite recursion.
         if (annotationClass != Retention.class &&
             annotationClass != Inherited.class) {
-            Retention ret = annotationClass.getAnnotation(Retention.class);
+            JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess();
+            Map<Class<? extends Annotation>, Annotation> metaAnnotations =
+                AnnotationParser.parseSelectAnnotations(
+                    jla.getRawClassAnnotations(annotationClass),
+                    jla.getConstantPool(annotationClass),
+                    annotationClass,
+                    Retention.class, Inherited.class
+                );
+            Retention ret = (Retention) metaAnnotations.get(Retention.class);
             retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
-            inherited = annotationClass.isAnnotationPresent(Inherited.class);
+            inherited = metaAnnotations.containsKey(Inherited.class);
         }
+        else {
+            retention = RetentionPolicy.RUNTIME;
+            inherited = false;
     }
+    }
 
     /**
      * Returns the type that must be returned by the invocation handler
      * of a dynamic proxy in order to have the dynamic proxy return
      * the specified type (which is assumed to be a legal member type

@@ -203,13 +221,12 @@
 
     /**
      * For debugging.
      */
     public String toString() {
-        StringBuffer s = new StringBuffer("Annotation Type:" + "\n");
-        s.append("   Member types: " + memberTypes + "\n");
-        s.append("   Member defaults: " + memberDefaults + "\n");
-        s.append("   Retention policy: " + retention + "\n");
-        s.append("   Inherited: " + inherited);
-        return s.toString();
+        return "Annotation Type:\n" +
+               "   Member types: " + memberTypes + "\n" +
+               "   Member defaults: " + memberDefaults + "\n" +
+               "   Retention policy: " + retention + "\n" +
+               "   Inherited: " + inherited;
     }
 }