IntersectionType

I came across this code that uses a cast to assign a Lambda expression to a marker interface in Angelika Langer’s explanation.

Serializable f2
= (BiPredicate<String,String> & Serializable)
(s,t) -> s.equalsIgnoreCase(t);

As I was curious about this I tried to detect an intersection type (T extends String & @IntersectionType.TypeUse(value = 2) Serializable) and print the annotation applied on one of its bounds.

The result is

Annotation [] [com.test.IntersectionType.Test]
Annotation [[]] [java.lang.String]
Annotation [[]] [java.io.Serializable]

This could be a JDK 8 bug at this time. I am getting nothing.

I am using

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b123)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b65, mixed mode)

I presumed there is a javax.lang.model.type.IntersectionType that will match T extends String & Serializable. So I though there is a TypeMirror that I can check for that type. But it does not seem so.

I will update later when I get a proper result.

Update : The method is updated and it works partly. I am getting the intersection type. But I think one cannot get the annotation type of the intersection type directly because the annotation is applied on each of the bounds separately. So the old code(see the comments below) is sufficient but now the returned array is empty which could mean that this is a bug in itself.


Annotation [] [com.test.IntersectionType.Test]
Annotation [[]] [java.lang.String&java.io.Serializable]
Annotation [[]] [java.lang.String]
Annotation [[]] [java.io.Serializable]


public class IntersectionType {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    public @interface TypeUses {
        TypeUse[] value();
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    @Repeatable(TypeUses.class)
    protected @interface  TypeUse {
        int value();
    }

    //Intersection type
    class Test<T extends String & @IntersectionType.TypeUse(value = 2) Serializable>{

    }
}

Processor method


    private void processClassTypeParameters(Element e) {


        for (TypeParameterElement typeParameterElement : ((TypeElement) e).getTypeParameters()) {

            for( AnnotationMirror am  : typeParameterElement.getAnnotationMirrors() ){

                System.out.println( "Annotation [" + am + "] [" + typeParameterElement  + "]");


            }
            //Get the intersection type
            TypeVariable tv = (TypeVariable)typeParameterElement.asType();

            TypeMirror tm = tv.getUpperBound();
            //This may not return anything.(See explanation above)
            System.out.println( "Annotation [" + Arrays.asList( tm.getAnnotationsByType(com.test.IntersectionType.TypeUse.class)) + "] [" + tm  + "]");

            for (TypeMirror typeMirror : typeParameterElement.getBounds()) {
                //Commented section is not the right way
                //if( typeMirror instanceof javax.lang.model.type.IntersectionType) {

                //The following line returns an empty array most probably due to a different bug.
                    System.out.println( "Annotation [" + Arrays.asList(typeMirror.getAnnotationsByType(com.test.IntersectionType.TypeUse.class)) + "] [" + typeMirror  + "]");

                //}
            }
        }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: