8065172: More core reflection final and volatile annotations
Summary: more fiddling with "final" and "volatile" field modifiers
Reviewed-by: jfranck, plevart, psandoz
--- a/jdk/src/java.base/share/classes/sun/reflect/Label.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/Label.java Fri Nov 21 16:30:02 2014 -0800
@@ -52,7 +52,7 @@
final short patchBCI;
final int stackDepth;
}
- private List<PatchInfo> patches = new ArrayList<>();
+ private final List<PatchInfo> patches = new ArrayList<>();
public Label() {
}
--- a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java Fri Nov 21 16:30:02 2014 -0800
@@ -135,7 +135,7 @@
* be initialized and therefore must not be called until the
* first get/set of this field.
* @param field the field
- * @param override true if caller has overridden aaccessibility
+ * @param override true if caller has overridden accessibility
*/
public FieldAccessor newFieldAccessor(Field field, boolean override) {
checkInitted();
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Nov 21 16:30:02 2014 -0800
@@ -280,19 +280,25 @@
* be rare).
*/
private Method[] getMemberMethods() {
- if (memberMethods == null) {
- memberMethods = AccessController.doPrivileged(
- new PrivilegedAction<Method[]>() {
- public Method[] run() {
- final Method[] mm = type.getDeclaredMethods();
- validateAnnotationMethods(mm);
- AccessibleObject.setAccessible(mm, true);
- return mm;
- }
- });
+ Method[] value = memberMethods;
+ if (value == null) {
+ value = computeMemberMethods();
+ memberMethods = value;
}
- return memberMethods;
+ return value;
}
+
+ private Method[] computeMemberMethods() {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<Method[]>() {
+ public Method[] run() {
+ final Method[] methods = type.getDeclaredMethods();
+ validateAnnotationMethods(methods);
+ AccessibleObject.setAccessible(methods, true);
+ return methods;
+ }});
+ }
+
private transient volatile Method[] memberMethods = null;
/**
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java Fri Nov 21 16:30:02 2014 -0800
@@ -772,7 +772,7 @@
}
/**
- * Return an appropriate exception proxy for a mismatching array
+ * Returns an appropriate exception proxy for a mismatching array
* annotation where the erroneous array has the specified tag.
*/
private static ExceptionProxy exceptionProxy(int tag) {
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java Fri Nov 21 16:30:02 2014 -0800
@@ -115,7 +115,7 @@
/**
- * Figures out if conatiner class comes before containee class among the
+ * Figures out if container class comes before containee class among the
* keys of the given map.
*
* @return true if container class is found before containee class when
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Fri Nov 21 16:30:02 2014 -0800
@@ -55,7 +55,7 @@
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;
@@ -117,7 +117,7 @@
memberDefaults = new HashMap<String, Object>(0);
members = new HashMap<String, Method>(methods.length+1, 1.0f);
- for (Method method : methods) {
+ for (Method method : methods) {
if (method.getParameterTypes().length != 0)
throw new IllegalArgumentException(method + " has params");
String name = method.getName();
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java Fri Nov 21 16:30:02 2014 -0800
@@ -36,7 +36,7 @@
class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = 7844069490309503934L;
private Method member;
- private String foundType;
+ private final String foundType;
/**
* It turns out to be convenient to construct these proxies in
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java Fri Nov 21 16:30:02 2014 -0800
@@ -33,8 +33,8 @@
*/
public class EnumConstantNotPresentExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = -604662101303187330L;
- Class<? extends Enum<?>> enumType;
- String constName;
+ final Class<? extends Enum<?>> enumType;
+ final String constName;
public EnumConstantNotPresentExceptionProxy(Class<? extends Enum<?>> enumType,
String constName) {
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeNotPresentExceptionProxy.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeNotPresentExceptionProxy.java Fri Nov 21 16:30:02 2014 -0800
@@ -34,8 +34,8 @@
*/
public class TypeNotPresentExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = 5565925172427947573L;
- String typeName;
- Throwable cause;
+ final String typeName;
+ final Throwable cause;
public TypeNotPresentExceptionProxy(String typeName, Throwable cause) {
this.typeName = typeName;
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java Fri Nov 21 16:30:02 2014 -0800
@@ -76,11 +76,11 @@
* kind. Classes produced will be those that would be loaded by the
* defining class loader of the declaration <tt>d</tt> (if <tt>d</tt>
* is a type declaration, or by the defining loader of the declaring
- * class of <tt>d</tt> otherwise.
+ * class of <tt>d</tt> otherwise.
* <p> Type variables will be created or lookup as necessary in the
* scope <tt> s</tt>.
* @param d - the generic declaration (class, interface, method or
- * constructor) that thsi factory services
+ * constructor) that this factory services
* @param s the scope in which the factory will allocate and search for
* type variables
* @return an instance of <tt>CoreReflectionFactory</tt>
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/GenericsFactory.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/GenericsFactory.java Fri Nov 21 16:30:02 2014 -0800
@@ -42,7 +42,7 @@
* of a specific implementation by using this interface. For example,
* repositories of generic type information are initialized with a
* factory conforming to this interface, and use it to generate the
- * tpe information they are required to provide. As a result, such
+ * type information they are required to provide. As a result, such
* repository code can be shared across different reflective systems.
*/
public interface GenericsFactory {
@@ -60,7 +60,7 @@
TypeVariable<?> makeTypeVariable(String name,
FieldTypeSignature[] bounds);
/**
- * Return an instance of the <tt>ParameterizedType</tt> interface
+ * Returns an instance of the <tt>ParameterizedType</tt> interface
* that corresponds to a generic type instantiation of the
* generic declaration <tt>declaration</tt> with actual type arguments
* <tt>typeArgs</tt>.
@@ -123,7 +123,7 @@
/**
* Returns a (possibly generic) array type.
* If the component type is a parameterized type, it must
- * only have unbounded wildcard arguemnts, otherwise
+ * only have unbounded wildcard arguments, otherwise
* a MalformedParameterizedTypeException is thrown.
* @param componentType - the component type of the array
* @return a (possibly generic) array type.
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/parser/SignatureParser.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/parser/SignatureParser.java Fri Nov 21 16:30:02 2014 -0800
@@ -227,7 +227,7 @@
* "<" FormalTypeParameter+ ">"
*/
private FormalTypeParameter[] parseFormalTypeParameters(){
- List<FormalTypeParameter> ftps = new ArrayList<>(3);
+ List<FormalTypeParameter> ftps = new ArrayList<>(3);
assert(current() == '<'); // should not have been called at all
if (current() != '<') { throw error("expected '<'");}
advance();
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java Fri Nov 21 16:30:02 2014 -0800
@@ -53,10 +53,10 @@
/**
- * Returns a <tt>Type</tt> object representing the component type
+ * Returns a <tt>Type</tt> object representing the component type
* of this array.
*
- * @return a <tt>Type</tt> object representing the component type
+ * @return a <tt>Type</tt> object representing the component type
* of this array
* @since 1.5
*/
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java Fri Nov 21 16:30:02 2014 -0800
@@ -25,7 +25,9 @@
package sun.reflect.generics.reflectiveObjects;
+import java.lang.reflect.Type;
import sun.reflect.generics.factory.GenericsFactory;
+import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier;
@@ -54,4 +56,16 @@
// produce a reifying visitor (could this be typed as a TypeTreeVisitor?
protected Reifier getReifier(){return Reifier.make(getFactory());}
+ Type[] reifyBounds(FieldTypeSignature[] boundASTs) {
+ final int length = boundASTs.length;
+ final Type[] bounds = new Type[length];
+ // iterate over bound trees, reifying each in turn
+ for (int i = 0; i < length; i++) {
+ Reifier r = getReifier();
+ boundASTs[i].accept(r);
+ bounds[i] = r.getResult();
+ }
+ return bounds;
+ }
+
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Fri Nov 21 16:30:02 2014 -0800
@@ -51,17 +51,16 @@
*/
public class TypeVariableImpl<D extends GenericDeclaration>
extends LazyReflectiveObjectGenerator implements TypeVariable<D> {
- D genericDeclaration;
- private String name;
- // upper bounds - evaluated lazily
- private Type[] bounds;
+ private final D genericDeclaration;
+ private final String name;
- // The ASTs for the bounds. We are required to evaluate the bounds
- // lazily, so we store these at least until we are first asked
- // for the bounds. This also neatly solves the
- // problem with F-bounds - you can't reify them before the formal
- // is defined.
- private FieldTypeSignature[] boundASTs;
+ /**
+ * The upper bounds. Lazily converted from FieldTypeSignature[] to Type[].
+ * We are required to evaluate the bounds lazily, so we store them as ASTs
+ * until we are first asked for them. This also neatly solves the problem
+ * with F-bounds - you can't reify them before the formal is defined.
+ */
+ private volatile Object[] bounds;
// constructor is private to enforce access through static factory
private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs,
@@ -69,18 +68,7 @@
super(f);
genericDeclaration = decl;
name = n;
- boundASTs = bs;
- }
-
- // Accessors
-
- // accessor for ASTs for bounds. Must not be called after
- // bounds have been evaluated, because we might throw the ASTs
- // away (but that is not thread-safe, is it?)
- private FieldTypeSignature[] getBoundASTs() {
- // check that bounds were not evaluated yet
- assert(bounds == null);
- return boundASTs;
+ bounds = bs;
}
/**
@@ -123,7 +111,7 @@
* <li>Otherwise, B is resolved.
* </ul>
*
- * @throws <tt>TypeNotPresentException</tt> if any of the
+ * @throws <tt>TypeNotPresentException</tt> if any of the
* bounds refers to a non-existent type declaration
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
* bounds refer to a parameterized type that cannot be instantiated
@@ -132,34 +120,23 @@
* type variable
*/
public Type[] getBounds() {
- // lazily initialize bounds if necessary
- if (bounds == null) {
- FieldTypeSignature[] fts = getBoundASTs(); // get AST
- // allocate result array; note that
- // keeping ts and bounds separate helps with threads
- Type[] ts = new Type[fts.length];
- // iterate over bound trees, reifying each in turn
- for ( int j = 0; j < fts.length; j++) {
- Reifier r = getReifier();
- fts[j].accept(r);
- ts[j] = r.getResult();
- }
- // cache result
- bounds = ts;
- // could throw away bound ASTs here; thread safety?
+ Object[] value = bounds;
+ if (value instanceof FieldTypeSignature[]) {
+ value = reifyBounds((FieldTypeSignature[])value);
+ bounds = value;
}
- return bounds.clone(); // return cached bounds
+ return (Type[])value.clone();
}
/**
- * Returns the <tt>GenericDeclaration</tt> object representing the
+ * Returns the <tt>GenericDeclaration</tt> object representing the
* generic declaration that declared this type variable.
*
* @return the generic declaration that declared this type variable.
*
* @since 1.5
*/
- public D getGenericDeclaration(){
+ public D getGenericDeclaration() {
if (genericDeclaration instanceof Class)
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
else if ((genericDeclaration instanceof Method) ||
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java Fri Nov 21 16:30:02 2014 -0800
@@ -39,25 +39,26 @@
*/
public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
implements WildcardType {
- // upper bounds - evaluated lazily
- private Type[] upperBounds;
- // lower bounds - evaluated lazily
- private Type[] lowerBounds;
- // The ASTs for the bounds. We are required to evaluate the bounds
- // lazily, so we store these at least until we are first asked
- // for the bounds. This also neatly solves the
- // problem with F-bounds - you can't reify them before the formal
- // is defined.
- private FieldTypeSignature[] upperBoundASTs;
- private FieldTypeSignature[] lowerBoundASTs;
+
+ /*
+ * We are required to evaluate the bounds lazily, so we store them as ASTs
+ * until we are first asked for them. This also neatly solves the problem
+ * with F-bounds - you can't reify them before the formal is defined.
+ */
+
+ /** The upper bounds. Lazily converted from FieldTypeSignature[] to Type[]. */
+ private volatile Object[] upperBounds;
+
+ /** The lower bounds. Lazily converted from FieldTypeSignature[] to Type[]. */
+ private volatile Object[] lowerBounds;
// constructor is private to enforce access through static factory
private WildcardTypeImpl(FieldTypeSignature[] ubs,
FieldTypeSignature[] lbs,
GenericsFactory f) {
super(f);
- upperBoundASTs = ubs;
- lowerBoundASTs = lbs;
+ upperBounds = ubs;
+ lowerBounds = lbs;
}
/**
@@ -76,27 +77,8 @@
return new WildcardTypeImpl(ubs, lbs, f);
}
- // Accessors
-
- // accessor for ASTs for upper bounds. Must not be called after upper
- // bounds have been evaluated, because we might throw the ASTs
- // away (but that is not thread-safe, is it?)
- private FieldTypeSignature[] getUpperBoundASTs() {
- // check that upper bounds were not evaluated yet
- assert(upperBounds == null);
- return upperBoundASTs;
- }
- // accessor for ASTs for lower bounds. Must not be called after lower
- // bounds have been evaluated, because we might throw the ASTs
- // away (but that is not thread-safe, is it?)
- private FieldTypeSignature[] getLowerBoundASTs() {
- // check that lower bounds were not evaluated yet
- assert(lowerBounds == null);
- return lowerBoundASTs;
- }
-
/**
- * Returns an array of <tt>Type</tt> objects representing the upper
+ * Returns an array of <tt>Type</tt> objects representing the upper
* bound(s) of this type variable. Note that if no upper bound is
* explicitly declared, the upper bound is <tt>Object</tt>.
*
@@ -117,24 +99,12 @@
* for any reason
*/
public Type[] getUpperBounds() {
- // lazily initialize bounds if necessary
- if (upperBounds == null) {
- FieldTypeSignature[] fts = getUpperBoundASTs(); // get AST
-
- // allocate result array; note that
- // keeping ts and bounds separate helps with threads
- Type[] ts = new Type[fts.length];
- // iterate over bound trees, reifying each in turn
- for ( int j = 0; j < fts.length; j++) {
- Reifier r = getReifier();
- fts[j].accept(r);
- ts[j] = r.getResult();
- }
- // cache result
- upperBounds = ts;
- // could throw away upper bound ASTs here; thread safety?
+ Object[] value = upperBounds;
+ if (value instanceof FieldTypeSignature[]) {
+ value = reifyBounds((FieldTypeSignature[])value);
+ upperBounds = value;
}
- return upperBounds.clone(); // return cached bounds
+ return (Type[])value.clone();
}
/**
@@ -160,23 +130,12 @@
* for any reason
*/
public Type[] getLowerBounds() {
- // lazily initialize bounds if necessary
- if (lowerBounds == null) {
- FieldTypeSignature[] fts = getLowerBoundASTs(); // get AST
- // allocate result array; note that
- // keeping ts and bounds separate helps with threads
- Type[] ts = new Type[fts.length];
- // iterate over bound trees, reifying each in turn
- for ( int j = 0; j < fts.length; j++) {
- Reifier r = getReifier();
- fts[j].accept(r);
- ts[j] = r.getResult();
- }
- // cache result
- lowerBounds = ts;
- // could throw away lower bound ASTs here; thread safety?
+ Object[] value = lowerBounds;
+ if (value instanceof FieldTypeSignature[]) {
+ value = reifyBounds((FieldTypeSignature[])value);
+ lowerBounds = value;
}
- return lowerBounds.clone(); // return cached bounds
+ return (Type[])value.clone();
}
public String toString() {
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java Fri Nov 21 16:30:02 2014 -0800
@@ -56,7 +56,7 @@
/**
* Returns a <tt>Reifier</tt> used to convert parts of the
* AST into reflective objects.
- * @return a <tt>Reifier</tt> used to convert parts of the
+ * @return a <tt>Reifier</tt> used to convert parts of the
* AST into reflective objects
*/
protected Reifier getReifier(){return Reifier.make(getFactory());}
@@ -76,7 +76,7 @@
}
/**
- * Returns the AST for the genric type info of this entity.
+ * Returns the AST for the generic type info of this entity.
* @param s - a string representing the generic signature of this
* entity
* @return the AST for the generic type info of this entity.
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ClassRepository.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ClassRepository.java Fri Nov 21 16:30:02 2014 -0800
@@ -25,12 +25,12 @@
package sun.reflect.generics.repository;
+import java.lang.reflect.Type;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.ClassSignature;
import sun.reflect.generics.tree.TypeTree;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.generics.parser.SignatureParser;
-import java.lang.reflect.Type;
/**
@@ -70,47 +70,54 @@
return new ClassRepository(rawSig, f);
}
- // public API
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
- * using a visitor.
- * a visitor, which is created by feeding it the factory
+ * using a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
public Type getSuperclass() {
- Type superclass = this.superclass;
- if (superclass == null) { // lazily initialize superclass
- Reifier r = getReifier(); // obtain visitor
- // Extract superclass subtree from AST and reify
- getTree().getSuperclass().accept(r);
- // extract result from visitor and cache it
- superclass = r.getResult();
- this.superclass = superclass;
+ Type value = superclass;
+ if (value == null) {
+ value = computeSuperclass();
+ superclass = value;
}
- return superclass; // return cached result
+ return value;
}
public Type[] getSuperInterfaces() {
- Type[] superInterfaces = this.superInterfaces;
- if (superInterfaces == null) { // lazily initialize super interfaces
- // first, extract super interface subtree(s) from AST
- TypeTree[] ts = getTree().getSuperInterfaces();
- // create array to store reified subtree(s)
- superInterfaces = new Type[ts.length];
- // reify all subtrees
- for (int i = 0; i < ts.length; i++) {
- Reifier r = getReifier(); // obtain visitor
- ts[i].accept(r);// reify subtree
- // extract result from visitor and store it
- superInterfaces[i] = r.getResult();
- }
- this.superInterfaces = superInterfaces;
+ Type[] value = superInterfaces;
+ if (value == null) {
+ value = computeSuperInterfaces();
+ superInterfaces = value;
}
- return superInterfaces.clone(); // return cached result
+ return value.clone();
+ }
+
+ private Type computeSuperclass() {
+ Reifier r = getReifier(); // obtain visitor
+ // Extract superclass subtree from AST and reify
+ getTree().getSuperclass().accept(r);
+ return r.getResult();
+ }
+
+ private Type[] computeSuperInterfaces() {
+ // first, extract super interface subtree(s) from AST
+ TypeTree[] ts = getTree().getSuperInterfaces();
+ // create array to store reified subtree(s)
+ int length = ts.length;
+ Type[] superInterfaces = new Type[length];
+ // reify all subtrees
+ for (int i = 0; i < length; i++) {
+ Reifier r = getReifier(); // obtain visitor
+ ts[i].accept(r);// reify subtree
+ // extract result from visitor and store it
+ superInterfaces[i] = r.getResult();
+ }
+ return superInterfaces;
}
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ConstructorRepository.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ConstructorRepository.java Fri Nov 21 16:30:02 2014 -0800
@@ -43,8 +43,11 @@
public class ConstructorRepository
extends GenericDeclRepository<MethodTypeSignature> {
- private Type[] paramTypes; // caches the generic parameter types info
- private Type[] exceptionTypes; // caches the generic exception types info
+ /** The generic parameter types. Lazily initialized. */
+ private volatile Type[] parameterTypes;
+
+ /** The generic exception types. Lazily initialized. */
+ private volatile Type[] exceptionTypes;
// protected, to enforce use of static factory yet allow subclassing
protected ConstructorRepository(String rawSig, GenericsFactory f) {
@@ -64,57 +67,67 @@
* @return a <tt>ConstructorRepository</tt> that manages the generic type
* information represented in the signature <tt>rawSig</tt>
*/
- public static ConstructorRepository make(String rawSig,
- GenericsFactory f) {
+ public static ConstructorRepository make(String rawSig, GenericsFactory f) {
return new ConstructorRepository(rawSig, f);
}
- // public API
-
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
- * using a visitor.
- * a visitor, which is created by feeding it the factory
+ * using a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
- public Type[] getParameterTypes(){
- if (paramTypes == null) { // lazily initialize parameter types
- // first, extract parameter type subtree(s) from AST
- TypeSignature[] pts = getTree().getParameterTypes();
- // create array to store reified subtree(s)
- Type[] ps = new Type[pts.length];
- // reify all subtrees
- for (int i = 0; i < pts.length; i++) {
- Reifier r = getReifier(); // obtain visitor
- pts[i].accept(r); // reify subtree
- // extract result from visitor and store it
- ps[i] = r.getResult();
- }
- paramTypes = ps; // cache overall result
+ public Type[] getParameterTypes() {
+ Type[] value = parameterTypes;
+ if (value == null) {
+ value = computeParameterTypes();
+ parameterTypes = value;
}
- return paramTypes.clone(); // return cached result
+ return value.clone();
+ }
+
+ public Type[] getExceptionTypes() {
+ Type[] value = exceptionTypes;
+ if (value == null) {
+ value = computeExceptionTypes();
+ exceptionTypes = value;
+ }
+ return value.clone();
}
- public Type[] getExceptionTypes(){
- if (exceptionTypes == null) { // lazily initialize exception types
- // first, extract exception type subtree(s) from AST
- FieldTypeSignature[] ets = getTree().getExceptionTypes();
- // create array to store reified subtree(s)
- Type[] es = new Type[ets.length];
- // reify all subtrees
- for (int i = 0; i < ets.length; i++) {
- Reifier r = getReifier(); // obtain visitor
- ets[i].accept(r); // reify subtree
- // extract result from visitor and store it
- es[i] = r.getResult();
- }
- exceptionTypes = es; // cache overall result
+ private Type[] computeParameterTypes() {
+ // first, extract parameter type subtree(s) from AST
+ TypeSignature[] pts = getTree().getParameterTypes();
+ // create array to store reified subtree(s)
+ int length = pts.length;
+ Type[] parameterTypes = new Type[length];
+ // reify all subtrees
+ for (int i = 0; i < length; i++) {
+ Reifier r = getReifier(); // obtain visitor
+ pts[i].accept(r); // reify subtree
+ // extract result from visitor and store it
+ parameterTypes[i] = r.getResult();
}
- return exceptionTypes.clone(); // return cached result
+ return parameterTypes;
+ }
+
+ private Type[] computeExceptionTypes() {
+ // first, extract exception type subtree(s) from AST
+ FieldTypeSignature[] ets = getTree().getExceptionTypes();
+ // create array to store reified subtree(s)
+ int length = ets.length;
+ Type[] exceptionTypes = new Type[length];
+ // reify all subtrees
+ for (int i = 0; i < length; i++) {
+ Reifier r = getReifier(); // obtain visitor
+ ets[i].accept(r); // reify subtree
+ // extract result from visitor and store it
+ exceptionTypes[i] = r.getResult();
+ }
+ return exceptionTypes;
}
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/FieldRepository.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/FieldRepository.java Fri Nov 21 16:30:02 2014 -0800
@@ -41,7 +41,8 @@
*/
public class FieldRepository extends AbstractRepository<TypeSignature> {
- private Type genericType; // caches the generic type info
+ /** The generic type info. Lazily initialized. */
+ private volatile Type genericType;
// protected, to enforce use of static factory yet allow subclassing
protected FieldRepository(String rawSig, GenericsFactory f) {
@@ -61,31 +62,32 @@
* @return a <tt>FieldRepository</tt> that manages the generic type
* information represented in the signature <tt>rawSig</tt>
*/
- public static FieldRepository make(String rawSig,
- GenericsFactory f) {
+ public static FieldRepository make(String rawSig, GenericsFactory f) {
return new FieldRepository(rawSig, f);
}
- // public API
-
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
- * using a visitor.
- * a visitor, which is created by feeding it the factory
+ * using a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
- public Type getGenericType(){
- if (genericType == null) { // lazily initialize generic type
- Reifier r = getReifier(); // obtain visitor
- getTree().accept(r); // reify subtree
- // extract result from visitor and cache it
- genericType = r.getResult();
+ public Type getGenericType() {
+ Type value = genericType;
+ if (value == null) {
+ value = computeGenericType();
+ genericType = value;
}
- return genericType; // return cached result
+ return value;
+ }
+
+ private Type computeGenericType() {
+ Reifier r = getReifier(); // obtain visitor
+ getTree().accept(r); // reify subtree
+ return r.getResult(); // extract result from visitor
}
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java Fri Nov 21 16:30:02 2014 -0800
@@ -43,13 +43,12 @@
extends AbstractRepository<S> {
/** The formal type parameters. Lazily initialized. */
- private volatile TypeVariable<?>[] typeParams;
+ private volatile TypeVariable<?>[] typeParameters;
protected GenericDeclRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
}
- // public API
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
@@ -61,25 +60,31 @@
*/
/**
- * Return the formal type parameters of this generic declaration.
+ * Returns the formal type parameters of this generic declaration.
* @return the formal type parameters of this generic declaration
*/
public TypeVariable<?>[] getTypeParameters() {
- TypeVariable<?>[] typeParams = this.typeParams;
- if (typeParams == null) { // lazily initialize type parameters
- // first, extract type parameter subtree(s) from AST
- FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
- // create array to store reified subtree(s)
- typeParams = new TypeVariable<?>[ftps.length];
- // reify all subtrees
- for (int i = 0; i < ftps.length; i++) {
- Reifier r = getReifier(); // obtain visitor
- ftps[i].accept(r); // reify subtree
- // extract result from visitor and store it
- typeParams[i] = (TypeVariable<?>) r.getResult();
- }
- this.typeParams = typeParams; // cache overall result
+ TypeVariable<?>[] value = typeParameters;
+ if (value == null) {
+ value = computeTypeParameters();
+ typeParameters = value;
}
- return typeParams.clone(); // return cached result
+ return value.clone();
+ }
+
+ private TypeVariable<?>[] computeTypeParameters() {
+ // first, extract type parameter subtree(s) from AST
+ FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
+ // create array to store reified subtree(s)
+ int length = ftps.length;
+ TypeVariable<?>[] typeParameters = new TypeVariable<?>[length];
+ // reify all subtrees
+ for (int i = 0; i < length; i++) {
+ Reifier r = getReifier(); // obtain visitor
+ ftps[i].accept(r); // reify subtree
+ // extract result from visitor and store it
+ typeParameters[i] = (TypeVariable<?>) r.getResult();
+ }
+ return typeParameters;
}
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/MethodRepository.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/MethodRepository.java Fri Nov 21 16:30:02 2014 -0800
@@ -39,7 +39,8 @@
*/
public class MethodRepository extends ConstructorRepository {
- private Type returnType; // caches the generic return type info
+ /** The generic return type info. Lazily initialized. */
+ private volatile Type returnType;
// private, to enforce use of static factory
private MethodRepository(String rawSig, GenericsFactory f) {
@@ -59,18 +60,21 @@
return new MethodRepository(rawSig, f);
}
- // public API
-
public Type getReturnType() {
- if (returnType == null) { // lazily initialize return type
- Reifier r = getReifier(); // obtain visitor
- // Extract return type subtree from AST and reify
- getTree().getReturnType().accept(r);
- // extract result from visitor and cache it
- returnType = r.getResult();
- }
- return returnType; // return cached result
+ Type value = returnType;
+ if (value == null) {
+ value = computeReturnType();
+ returnType = value;
+ }
+ return value;
}
+ private Type computeReturnType() {
+ Reifier r = getReifier(); // obtain visitor
+ // Extract return type subtree from AST and reify
+ getTree().getReturnType().accept(r);
+ // extract result from visitor and cache it
+ return r.getResult();
+ }
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java Fri Nov 21 16:30:02 2014 -0800
@@ -29,7 +29,6 @@
import java.lang.reflect.TypeVariable;
-
/**
* Abstract superclass for lazy scope objects, used when building
* factories for generic information repositories.
@@ -49,7 +48,7 @@
/**
* Constructor. Takes a reflective object whose scope the newly
* constructed instance will represent.
- * @param D - A generic declaration whose scope the newly
+ * @param decl - A generic declaration whose scope the newly
* constructed instance will represent
*/
protected AbstractScope(D decl){ recvr = decl;}
@@ -63,7 +62,7 @@
/** This method must be implemented by any concrete subclass.
* It must return the enclosing scope of this scope. If this scope
- * is a top-level scope, an instance of DummyScope must be returned.
+ * is a top-level scope, an instance of DummyScope must be returned.
* @return The enclosing scope of this scope
*/
protected abstract Scope computeEnclosingScope();
@@ -72,13 +71,13 @@
* Accessor for the enclosing scope, which is computed lazily and cached.
* @return the enclosing scope
*/
- protected Scope getEnclosingScope(){
- Scope enclosingScope = this.enclosingScope;
- if (enclosingScope == null) {
- enclosingScope = computeEnclosingScope();
- this.enclosingScope = enclosingScope;
+ protected Scope getEnclosingScope() {
+ Scope value = enclosingScope;
+ if (value == null) {
+ value = computeEnclosingScope();
+ enclosingScope = value;
}
- return enclosingScope;
+ return value;
}
/**
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/Signature.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/Signature.java Fri Nov 21 16:30:02 2014 -0800
@@ -27,7 +27,7 @@
/**
* Common superinterface for generic signatures. These are the signatures
- * of complete class and method/constructor delcarations.
+ * of complete class and method/constructor declarations.
*/
public interface Signature extends Tree{
FormalTypeParameter[] getFormalTypeParameters();
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/Wildcard.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/Wildcard.java Fri Nov 21 16:30:02 2014 -0800
@@ -28,8 +28,8 @@
import sun.reflect.generics.visitor.TypeTreeVisitor;
public class Wildcard implements TypeArgument {
- private FieldTypeSignature[] upperBounds;
- private FieldTypeSignature[] lowerBounds;
+ private final FieldTypeSignature[] upperBounds;
+ private final FieldTypeSignature[] lowerBounds;
private Wildcard(FieldTypeSignature[] ubs, FieldTypeSignature[] lbs) {
upperBounds = ubs;
@@ -43,11 +43,11 @@
return new Wildcard(ubs, lbs);
}
- public FieldTypeSignature[] getUpperBounds(){
+ public FieldTypeSignature[] getUpperBounds() {
return upperBounds;
}
- public FieldTypeSignature[] getLowerBounds(){
+ public FieldTypeSignature[] getLowerBounds() {
if (lowerBounds.length == 1 &&
lowerBounds[0] == BottomSignature.make())
return emptyBounds;
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/visitor/Reifier.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/visitor/Reifier.java Fri Nov 21 16:30:02 2014 -0800
@@ -39,7 +39,7 @@
*/
public class Reifier implements TypeTreeVisitor<Type> {
private Type resultType;
- private GenericsFactory factory;
+ private final GenericsFactory factory;
private Reifier(GenericsFactory f){
factory = f;
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java Fri Nov 21 16:30:02 2014 -0800
@@ -40,6 +40,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import sun.misc.IOUtils;
@@ -216,17 +217,21 @@
* key in the method cache.
*/
private static class Signature {
- private String methodName;
- private Class<?>[] argClasses;
-
- private volatile int hashCode = 0;
+ private final String methodName;
+ private final Class<?>[] argClasses;
+ private final int hashCode;
Signature(Method m) {
this.methodName = m.getName();
this.argClasses = m.getParameterTypes();
+ this.hashCode = methodName.hashCode() + Arrays.hashCode(argClasses);
}
- public boolean equals(Object o2) {
+ @Override public int hashCode() {
+ return hashCode;
+ }
+
+ @Override public boolean equals(Object o2) {
if (this == o2) {
return true;
}
@@ -244,25 +249,6 @@
}
return true;
}
-
- /**
- * Hash code computed using algorithm suggested in
- * Effective Java, Item 8.
- */
- public int hashCode() {
- if (hashCode == 0) {
- int result = 17;
- result = 37 * result + methodName.hashCode();
- if (argClasses != null) {
- for (int i = 0; i < argClasses.length; i++) {
- result = 37 * result + ((argClasses[i] == null) ? 0 :
- argClasses[i].hashCode());
- }
- }
- hashCode = result;
- }
- return hashCode;
- }
}
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Fri Dec 12 15:35:21 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Fri Nov 21 16:30:02 2014 -0800
@@ -319,7 +319,7 @@
return;
}
- // disallow any method not declared in one of the proxy intefaces
+ // disallow any method not declared in one of the proxy interfaces
throw new IllegalArgumentException("Can't handle: " + method);
}