JDK 8 RFR, redux, for JDK-8005294 : Consider default methods for additions to AnnotatedElement
Joe Darcy
joe.darcy at oracle.com
Wed Oct 30 01:57:15 UTC 2013
On 10/29/2013 06:37 PM, Joe Darcy wrote:
> Hi Joel,
>
> On 10/29/2013 09:20 AM, Joel Borggrén-Franck wrote:
>> Hi Joe, Peter,
>>
>> On 29 okt 2013, at 07:09, Joe Darcy <joe.darcy at oracle.com> wrote:
>>> Your comments, along with some spec refinements from the other
>>> OpenJDK list, are reflected in the next iteration of the webrev:
>>>
>>> http://cr.openjdk.java.net/~darcy/8005294.5/
>>>
>>> Thanks,
>>>
>> 259 if (result.length == 0 && // Neither directly nor
>> indirectly present
>> 260 this instanceof Class && // the element is a class
>> 261 AnnotationType.getInstance(annotationClass).isInherited()) { //
>> Inheritable
>> 262 ...
>>
>> j.l.Class is final and has an implementation of getAnnotationsByType
>> so everything in this branch is dead code. I understand you might
>> want to document how the lookup is supposed to happen if you have
>> inheritance semantics for your AnnotatedElement but IMHO this isn't
>> the way to do it. Just delegate to getDeclaredAnnotationsByType.
>
> Summarizing an off-list discussion, in terms of making this particular
> method robust in the face of of possible alternative versions of
> java.lang.Class and friends, I think it is acceptable to introduce
> what will in practice be dead code with the version of java.lang.Class
> in JDK 8.
>
>>
>> 291 * @since 1.8
>> 292 */
>>
>> 293 default <T extends Annotation> T
>> getDeclaredAnnotation(Class<T> annotationClass) {
>>
>> I keep forgetting that this one is new to 8. My reservations about
>> making this a default was based on (the misconception) that this was
>> a 5 method. This method looks good.
>>
>> For getDeclaredAnnotationsByType() the idea of having two
>> implementations of the same logic, one taking arrays as arguments and
>> the other Maps, seems wrong. I would strongly prefer if we only had
>> one implementation, calling into AnnotationSupport from this method.
>> Something like
>>
>> default <T extends Annotation> T[]
>> getDeclaredAnnotationsByType(Class<T> annotationClass) {
>> Objects.requireNonNull(annotationClass);
>> return
>> AnnotationSupport.getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).collect(Collectors.toMap(
>> (a -> a.getClass()),
>> Function.identity())),
>> annotationClass);
>> }
>>
>> I can't see these default methods as the code we should be spending
>> time optimizing.
>
> Given the improved maintenance situation and the low expecte duty
> cycle of the default method implementations, despite having worked on
> what should be a fast-ish getDeclaredAnnotation implementation, I'm
> willing to replace it by a call to AnnotationSupport wrapped around a
> call to getDeclaredAnnotations().
>
> This style of implementation is allowed by the current @implSpec for
> the method.
>
> However, I'm not sure the
> AnnotationSupport.getDirectlyAndIndirectlyPresent call can work as
> currently formulated will work since I believe what needs to be called
> is "a.getAnnotationType()" rather than "a.getClass()", but
> unfortunately "getAnnotationType()" is not defined on AnnotatedElement
> so reflection would be needed to call getAnnotationType :-(
>
I retract my previous comments; I was confusing "annotationType" and
"value()" in terms of where they are defined. This version of
getDeclaredAnnotationsByType passes the battery of regression tests:
default <T extends Annotation> T[]
getDeclaredAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.
getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).
collect(Collectors.toMap(
(a -> a.annotationType()),
Function.identity(),
((first,second) -> first),
() -> new LinkedHashMap<>() )),
annotationClass);
}
I've prepared a new version of the webrev with this change as well as a
slightly-refactored regression test:
http://cr.openjdk.java.net/~darcy/8005294.6
Thanks,
-Joe
More information about the core-libs-dev
mailing list