This is too long for comment.
From the point of view of the compiler, a restriction that may be false is not a restriction at all and will not help it determine which types should be allowed in different parameter slots, or what you are allowed to do with them. Thus, the language (neither C # nor Java, by the way) has syntax for defining one way or another. The reason for allowing type restrictions is that it allows you to process the variable as if it were that type in the method body. Thus:
public static <T extends Collection> void foo(T a) { System.out.println(a.size()); }
It will compile and execute because all subclasses of Collection have a size() method. The problem is that <T extends S || S extends T> <T extends S || S extends T> (or any other compiled syntax) does not help.
For example, suppose we had this:
public static <T extends List || S extends ArrayList> S bar(T a, S b) {
Is it possible to call b.removeRange(...) in this example? We have no idea, because S may not be an ArrayList . What about a.size() ? Again, we do not know, because T may not be a List . So this is no better than if we just said
public static <T, S> S bar(T a, S b) {...}
Adding that they may come from one another adds an extra level of complexity to this example.
Ian mclaird
source share