Spring Batch 5.1.1's ListItemWriter<T>::getWrittenItems has the bounded wildcard generic return type List<? extends T>. It is evident from the field's type, List<T>, that the method return type's bounded wildcard contributes nothing of value, but besides this some constructs end up inferring the specific element type ? extends T where only a T can work, necessitating otherwise redundant explicit type parameter specification. This ergonomics breakage manifests trivially in AssertJ's ListAssert<ELEMENT>, which happens to feature an API that appears counter-productively genericized, but it is easy to show with plain JDK APIs that the correct return type should be List<T>; consider:
import java.util.*;
class T {
void foo() {
var writer = new LiWr<Element>();
var without = writer.itemsWithoutWildcard(); // List<Element>
var mutableWithout = new ArrayList<>(without); // ArrayList<Element>
mutableWithout.add(new Element());
// T.java:18: error: incompatible types: Element cannot be converted to CAP#1
// mutableWith.add(new Element());
// ^
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Element from capture of ? extends Element
var with = writer.itemsWithWildcard(); // List<? extends Element>
var mutableWith = new ArrayList<>(with); // ArrayList<? extends Element>
mutableWith.add(new Element());
// T.java:25: error: incompatible types: List<CAP#1> cannot be converted to List<Element>
// List<Element> with2 = writer.itemsWithWildcard(); // List<? extends Element>
// ^
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Element from capture of ? extends Element
List<Element> with2 = writer.itemsWithWildcard(); // List<? extends Element>
// ok
var with3 = writer.itemsWithWildcard();
List<Element> mutableWith2 = new ArrayList<>(with);
}
}
class LiWr<T> {
final List<T> writtenItems = new ArrayList<>();
List<? extends T> itemsWithWildcard() { return this.writtenItems; }
List<T> itemsWithoutWildcard() { return this.writtenItems; }
}
class Element {}
Effective Java 3rd Ed. item 32 also says
Do not use bounded wildcard tyeps as return types.
Spring Batch 5.1.1's
ListItemWriter<T>::getWrittenItemshas the bounded wildcard generic return typeList<? extends T>. It is evident from the field's type,List<T>, that the method return type's bounded wildcard contributes nothing of value, but besides this some constructs end up inferring the specific element type? extends Twhere only aTcan work, necessitating otherwise redundant explicit type parameter specification. This ergonomics breakage manifests trivially in AssertJ'sListAssert<ELEMENT>, which happens to feature an API that appears counter-productively genericized, but it is easy to show with plain JDK APIs that the correct return type should beList<T>; consider:Effective Java 3rd Ed. item 32 also says