Search code examples
javatypesjava-7intersectionjls

Java 7 intersection types: what exactly does the specification say?


http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.9

  • For each Ti (1 ≤ i ≤ n), let Ci be the most specific class or array type such that Ti <: Ci. Then there must be some Tk <: Ck such that Ck <: Ci for any i (1 ≤ i ≤ n), or a compile-time error occurs.

  • For 1 ≤ j ≤ n, if Tj is a type variable, then let Tj' be an interface whose members are the same as the public members of Tj; otherwise, if Tj is an interface, then let Tj' be Tj.

  • Then the intersection type has the same members as a class type (§8) with an empty body, direct superclass Ck and direct superinterfaces T1', ..., Tn', declared in the same package in which the intersection type appears.

I would have expected the following code to cause a compile-time error, but it doesn't:

public interface I1 {}
public interface J1 extends I1 {}
public interface J2 {}
public interface J3 extends J2 {}

class C implements J1, J3 {}

public class A<T extends J1 & J3> {
    public static void main(String[] args) {
        A<C> a = new A<>();
    }

}

As far as I understand, the Ti <: Ci types are as follows:

  • J1 <: I1
  • J3 <: J2

Now, I would need to have a Tk <: Ck, where Ck <: C1 and Ck <: C2, but if Ck := C1, then I1 <: J2 is false, and if Ck := C2, then J2 <: I1 is false.

What am I missing here?


Solution

  • You seem to confuse <: and <. If you read the next section about subtyping, you will see that <: is valid for a class itself - in other words, for any type T, T <: T is true. This is as opposed to < which is used for strict subclassing (T < T is always false).

    In your example:

    • T1 == C1 == J1
    • T2 == C2 == J2
    • Tk == Ck == C

    and you can verify that C <: J1 and C <: J2.

    So it all looks fine.