Generics
generics: ? extends は読む側、? super は書く側の境界
extends はサブタイプから読み、super はスーパタイプのコンテナへ値を書き込みます。
SourceGenericBounds.java
Java 21
package examples.generics;
import java.util.List;
public final class GenericBounds {
private GenericBounds() {}
public static double sum(List<? extends Number> values) {
return values.stream().mapToDouble(Number::doubleValue).sum();
}
public static void addDefaults(List<? super Integer> target) {
target.add(1);
target.add(2);
}
}TestGenericBoundsTest.java
Java 21
package examples.generics;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
class GenericBoundsTest {
@Test
void extendsはIntegerのListをNumberとして読み取れる() {
assertEquals(3.0, GenericBounds.sum(List.of(1, 2)));
}
@Test
void superはNumberのListへIntegerを追加できる() {
List<Number> numbers = new ArrayList<>();
GenericBounds.addDefaults(numbers);
assertEquals(List.of(1, 2), numbers);
}
}01Assertion
このテストで確認できること
- ? extends Number は Integer の List を Number として読める
- ? super Integer は Number の List へ Integer を書き込める
PECS(Producer Extends, Consumer Super)として覚えると、値を読むのか書くのかで境界を選べます。
OBSERVED RESULT
expected: sum([1, 2]) → 3.0
actual: 3.0
expected: target → [1, 2]