These are not expressions but declarations. Expressions are parts of a statement that return a value. In programming, it's important to use the correct terminology.
First you declare an interface Foo with a generic type parameter T. We say "Foo of T".
Secondly you declare a class FooImpl with a generic type parameter U. U has an upper type boundary of Foo<? super U>. We say "FooImpl of U, where U is some subtype of a Foo that consumes U".
You are probably wondering about the "U is some subclass of a Foo that consumes U" part. I will be able to explain it a bit better using types that have more meaning than Foo and FooImpl:
SortedSequence maintains a sorted list of items. You can insert a new item and it will perform a binary search on the current list of items to find the index where the item will be inserted.
To make all of this work, the items need to be comparable to each other. That's why U extends Comparable. However, Comparable is also a generic type, so we need to specify type arguments: U extends Comparable<U> because the items need to be comparable to themselves.
So why does the actual declaration read U extends Comparable<? super U> ? That's because otherwise we'd be needlessly limiting the type of things we can make a sorted sequence of. Here's an example:
Why is it not possible to create a sequence of sheep, even though Sheep extends Animal and Animal is comparable to itself? Well, SortedSequence requires something that extends Comparable<Sheep>, and Sheep is not a Comparable<Sheep> but a Comparable<Animal>.
When instead we declare U as U extends Comparable<? super U>, we CAN create a SortedSequence<Sheep>, because the SortedSequence requires something that extends Comparable<? super Sheep>, and Comparable<Animal> does just that.
Finally, why do we say "consumes" in "SortedSequence of U, where U is some subtype of a Comparable that consumes U"? Well, the super keyword is used to specify a lower type bound on types that contain methods that only have the generic type in their method parameters, not in their return values. Comparable has T as a parameter in its compareTo method, and not in its return type. That's why we can use the super keyword, and that's why we say "Comparable that consumes U".
He was giving me directions and I was powerless to resist. I cannot resist this tiny ad: