RFR: 8029019: (ann) Optimize annotation handling in core reflection

Christoph Dreis christoph.dreis at freenet.de
Fri Oct 13 06:55:03 UTC 2017

Hi Peter,

Thanks for your feedback!

> Method.getName() returns an interned String and String literals are interned strings. Reference comparison is therefore possible
Good point. 

> The pair (declaringClass, methodName) uniquely identifies the method for a bunch of interesting methods when declaringClass is either java.lang.Object or java.lang.annotation.Annotation, so we don't need to obtain method's parameterTypes even for equals().
Forgive me the maybe stupid question, but isn't your proposed code changing semantics because it doesn't check for the first parameter in equals() to be of type java.lang.Object anymore? E.g. like "method.getParameterTypes()[0] == Object.class". Am I missing something? Personally, I find this a bit too "magic" overall. I don't know what Claes thinks about that. 

I would settle on this, if I include the reference comparison change of yours. 

For example:

   public Object invoke(Object proxy, Method method, Object[] args) {
        String memberName = method.getName(); // guaranteed interned String
        int parameterCount = method.getParameterCount();

        // Handle Object and Annotation methods
        if (parameterCount == 1 && memberName == "equals" &&
            method.getParameterTypes()[0] == Object.class)
            return equalsImpl(proxy, args[0]);
        if (parameterCount != 0)
            throw new AssertionError("Too many parameters for an annotation method");

        if (memberName == "hashCode") return hashCodeImpl();
        if (memberName == "annotationType") return type;
        if (memberName == "toString") return toStringImpl();

        // Handle annotation member accessors
        Object result = memberValues.get(memberName);

        if (result == null)
            throw new IncompleteAnnotationException(type, memberName);

        if (result instanceof ExceptionProxy)
            throw ((ExceptionProxy) result).generateException();

        if (result.getClass().isArray() && Array.getLength(result) != 0)
            result = cloneArray(result);

        return result;

What do you think?


More information about the core-libs-dev mailing list