Reputation: 1319
I can't understand why the method2 does not compile whereas method1 does compile. I am using Eclipse with JavaSE 1.7 and I got the following error on method2:
Multiple markers at this line
The type Enum<T> is not an interface; it cannot be specified as a bounded parameter
Bound mismatch: The type T is not a valid substitute for the bounded parameter <E extends Enum<E>> of the type Enum<E>
public class Test {
public interface SomeInterface {
}
public static <T extends Enum<T> & SomeInterface> T method1() {
return null;
}
public static <T extends SomeInterface & Enum<T>> T method2() {
return null;
}
}
Upvotes: 13
Views: 1803
Reputation: 4540
According to the docs:
A type variable with multiple bounds is a subtype of all the types listed in the bound. If one of the bounds is a class, it must be specified first. For example:
Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }
class D <T extends A & B & C> { /* ... */ }
If bound A is not specified first, you get a compile-time error:
class D <T extends B & A & C> { /* ... */ } // compile-time error
Since in your example method2
has the interface SomeInterface
first, it shows the compiler-error
Upvotes: 6
Reputation: 1503050
If you look at the syntax for type parameter bounds in JLS 8.1.2 you'll see:
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
AdditionalBound:
& InterfaceType
In other words, only the first type specified can be a class - all the rest have to be interfaces.
Aside from anything else, this prevents multiple classes being specified.
It also mirrors the way that when declaring a class, you have to put the class it's extending first, then the interfaces it implements - not the other way round.
Upvotes: 18