Java intersection type restrictions with interface classes and type variables

Today I tried to write a class using a generic method that uses intersection types and gets confused by various error messages depending on the intersecting types. Suppose we have an interface and a class and define common methods in a common interface:

 class ClassType { } interface InterfaceType { } interface I<T> { public <X extends InterfaceType & InterfaceType> void foo(); public <X extends ClassType & ClassType> void foo1(); public <X extends ClassType & InterfaceType> void foo2(); public <X extends InterfaceType & ClassType> void foo3(); public <X extends T & ClassType> void foo4(); public <X extends ClassType & T> void foo5(); public <X extends InterfaceType & T> void foo6(); public <X extends T & InterfaceType> void foo7(); } 

When compiling, this leads to errors for the whole method except public <X extends ClassType & InterfaceType> void foo2(); .

 Main.java:8: error: repeated interface public <X extends InterfaceType & InterfaceType> void foo(); ^ Main.java:10: error: interface expected here public <X extends ClassType & ClassType> void foo1(); ^ Main.java:14: error: interface expected here public <X extends InterfaceType & ClassType> void foo3(); ^ Main.java:16: error: a type variable may not be followed by other bounds public <X extends T & ClassType> void foo4(); ^ Main.java:18: error: unexpected type public <X extends ClassType & T> void foo5(); ^ required: class found: type parameter T where T is a type-variable: T extends Object declared in interface I Main.java:20: error: unexpected type public <X extends InterfaceType & T> void foo6(); ^ required: class found: type parameter T where T is a type-variable: T extends Object declared in interface I Main.java:22: error: a type variable may not be followed by other bounds public <X extends T & InterfaceType> void foo7(); ^ 7 errors 

Since the intersection should be symmetrical, I am surprised that foo2 accepted, but foo3 rejected. Why is this case accepted?

I am also wondering why there is a difference between interfaces, classes, and type parameters when it comes to intersection types. I see reasons not to allow more than one class in the intersection type, but the current state accepting ClassType & InterfaceType but not InterfaceType & ClassType seems weird arbitrary. Intersection A & A also forbidden, but it is semantically identical to A , so I see no reason for this.

I am also curious why type variables are not allowed at the intersection. The worst case would be the intersection of two or more classes, but would just be an uninhabited type, so the lower type.

+2
source share
1 answer

You can only have 1 class, but there are several interfaces. If you have a class, it must be listed first. If you follow this rule, you should not receive compilation errors.

See https://docs.oracle.com/javase/tutorial/java/generics/bounded.html

+2
source

Source: https://habr.com/ru/post/1272853/


All Articles