public class Box {
private Object value;
public void set(Object value) {
this.value = value;
}
public Object get() {
return value;
}
} Box box = new Box();
box.set("Hello, world");
String text = (String) box.get();
System.out.println(text); Box box = new Box();
box.set(42); // Integer
String text = (String) box.get(); java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String List list = new ArrayList();
list.add("Hello");
list.add(10);
list.add(new Date()); String value = (String) list.get(1); public class Box<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
} Box<String> box = new Box<>();
box.set("Hello, world");
String text = box.get();
System.out.println(text); Box<String> box = new Box<>();
box.set(42); // ошибка компиляции Required type: String
Provided: int Box<String> box = new Box<>(); Box box = new Box(); public class Box<T> {
private T value;
} public class Box {
private Object value;
} public class Box<T> {
private T value;
} public class Box<T extends Number> {
private T value;
} public class Box<T extends Number & Comparable<T>> {
private T value;
} List list = new ArrayList(); List<String> list = new ArrayList<>(); new T(); // нельзя
T.class; // нельзя
instanceof T; // нельзя List<String> List String → Object String[] → Object[] String[] strings = new String[10];
Object[] objects = strings; public void printAll(Object[] array) {
for (Object o : array) {
System.out.println(o);
}
} String[] strings = new String[10];
Object[] objects = strings;
objects[0] = 42; // компилируется ArrayStoreException List<String> strings = new ArrayList<>();
List<Object> objects = strings; // если бы дженерики были ковариантными objects.add(42); String → Object List<String> ↛ List<Object> List<String> strings = new ArrayList<>();
List<Object> objects = strings; // ошибка компиляции public static <T> T identity(T value) {
return value;
} String text = identity("Hello");
Integer number = identity(42); public class Box<T> {
public T get() {
return value;
}
} public static <T> void print(T value) {
System.out.println(value);
} new T();
T.class;
value instanceof T; String[] strings = new String[10];
Object[] objects = strings; objects[0] = 42; // компилируется List<String> strings = new ArrayList<>();
List<Object> objects = strings; // ошибка компиляции public static void printAll(List<String> list) {
for (String s : list) {
System.out.println(s);
}
} public static void printAll(List<? extends CharSequence> list) {
for (CharSequence s : list) {
System.out.println(s);
}
} List<String>
List<StringBuilder>
List<CharSequence> list.add("text"); // ошибка компиляции List<? extends CharSequence> List<String>
List<StringBuilder> ChildClass → ParentClass class ParentClass { }
class ChildClass extends ParentClass { } List<ParentClass> parents = new ArrayList<>();
List<ChildClass> children = new ArrayList<>();
List<Object> objects = new ArrayList<>();
List<? super ChildClass> sink; sink = parents; // корректно: ParentClass — предок ChildClass
sink = children; // корректно: ChildClass — это сам T
sink = objects; // корректно: Object — предок всех ссылочных типов List<? super ParentClass> badSink = children; // ошибка компиляции public static void addHello(List<String> list) {
list.add("Hello");
} public static void addHello(List<? super String> list) {
list.add("Hello");
} List<String> strings = new ArrayList<>();
addHello(strings);
List<Object> objects = new ArrayList<>();
addHello(objects); List<? super String> List<? super String> list = new ArrayList<Object>();
list.add("A");
list.add("B"); Object value = list.get(0); // корректно
String text = list.get(0); // ошибка компиляции List<String> source = List.of("A", "B");
List<Object> target = new ArrayList<>(); public static <T> void addAll(List<? super T> target, List<T> source) {
for (T item : source) {
target.add(item);
}
} List<String> source = List.of("A", "B");
List<Object> target = new ArrayList<>();
addAll(target, source); public static <T> void copy(List<? super T> target, List<? extends T> source) {
for (T item : source) {
target.add(item);
}
}