Po kolei:
- Możesz oznaczyć typ generyczny jako dowolny:
/**
* Nie obchodzi nas jakiego typu to lista - dlatego korzystamy z <?>
*/
public static void withWildCard(final List<?> list, final List<?> secondList) {
System.out.println(list.size() + secondList.size());
}
public static void test() {
List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>();
// Obie wersje zadziałają - nie ma żadnych wymagań co do typu
withWildCard(stringList, integerList);
}
- Chcesz, żeby argumenty były zgodnego typu:
/**
* Chcemy zapewnić zgodność typu listy z przekazywanym elementem - przed void deklarujemy, że istnieje typ: <T>
* Potem zapisujemy, że List musi być <T>, oraz podany obiekt musi być tego samego typu
*/
public static <T> void withAnyType(final List<T> list, T element) {
list.add(element);
}
public static void test() {
List<String> stringList = new ArrayList<>();
withAnyType(stringList, 1); // nie zadziała bo stringList ma typ <String>, a 1 jest typu Integer
withAnyType(stringList, "1"); // to już zadziała bo stringList i "1" są tego samego typu
}
- Chcesz, żeby argumenty były konkretnego typu - tutaj implementowały Comparable:
/**
* Chcemy zapewnić, że typ będzie np. implementował interfejs - przed "void" dorzucamy <T extends Comparable<T>>
*/
public static <T extends Comparable<T>> void withComparableType(final T first, final T second) {
System.out.println("Compare: " + first.compareTo(second));
}
public static void test() {
Object nonComparableObject1 = new Object();
Object nonComparableObject2 = new Object();
withComparableType(nonComparableObject1, nonComparableObject2); // nie zadziała bo typ Object nie implementuje Comparable<Object>
Integer comparableObject1 = 1;
Integer comparableObject2 = 2;
withComparableType(comparableObject1, comparableObject2); // zadziała bo Integer implementuje Comparable<Integer>
String anotherComparableObject1 = "1";
String anotherComparableObject2 = "2";
withComparableType(anotherComparableObject1, anotherComparableObject2); // zadziała bo String implementuje Comparable<String>
withComparableType(comparableObject1, anotherComparableObject1); // nie zadziała - obiekty są innego typu
}