Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unrelated defaults inheritance error for type variables: why?

Disclaimer: this is not about this case (while error sounds as same): class inherits unrelated defaults for spliterator() from types java.util.Set and java.util.List

and here is why:

consider two interfaces (in package "a")

interface I1 {
    default void x() {}
}

interface I2 {
    default void x() {}
}

It is definitely clear to me why we can not declare such class as:

abstract class Bad12 implements I1, I2 {
}

(!) But I can not understand this restriction with reference to type variables:

class A<T extends I1&I2> {
    List<T> makeList() {
        return new ArrayList<>();
    }
}

with error: class java.lang.Object&a.I1&a.I2 inherits unrelated defaults for x() from types a.I1 and a.I2.

Why I can not define such type variable? Why java cares about unrelated defaults in this case? What such type variable could "break"?

UPDATE: Just for clarification. I can create several classes of the form:

class A1 implements I1, I2 {
    public void x() { };
}

class A2 implements I1, I2 {
    public void x() { };
}

and even

abstract class A0 implements I1, I2 {
    @Override
    public abstract void x();
}

and so on. Why I can not declare special kind of type variable for such group of classes?

UPD-2: BTW I didn't find any distinct restriction for this case in JLS. It would be nice to confirm your answer with references to JLS.

UPD-3: Some of users told that this code is compiled well in Eclipse. I can not check it, but I checked with javac and got this error:

 error: class INT#1 inherits unrelated defaults for x() from types I1 and I2
class A<T extends I1&I2> {
        ^
  where INT#1 is an intersection type:
    INT#1 extends Object,I1,I2
1 error
like image 991
Andremoniy Avatar asked Jan 06 '16 22:01

Andremoniy


1 Answers

This is simply a bug. It turns out that the bug starts in the specification, and then spills over into the implementation. Spec bug is here: https://bugs.openjdk.java.net/browse/JDK-7120669

The constraint is perfectly valid; it is clearly possible that there exist types T that extend both I1 and I2. The problem is how we validate the well-formedness of such types.

like image 108
Brian Goetz Avatar answered Nov 03 '22 10:11

Brian Goetz