Инвариантность
Инвариантность в Java - это свойство обобщённых типов,
при котором List<String> не является подтипом
List<Object> и наоборот. То есть параметризованные
типы с разными аргументами типа несовместимы между
собой, даже если сами аргументы типа находятся
в отношении наследования. Это правило действует
по умолчанию для всех обобщённых типов, если
не использовать вариативность через wildcard.
Параметров у этого механизма нет - это характеристика
системы типов, а не отдельного метода.
Синтаксис
List<String> list = new ArrayList<>();
// List<Object> obj = list; // compile error
Пример
Давайте попробуем присвоить List<String>
переменной типа List<Object> и посмотрим,
что произойдёт при компиляции:
import java.util.List;
import java.util.ArrayList;
public class Main
{
public static void main(String[] args)
{
List<String> list = new ArrayList<>();
list.add("abcde");
// List<Object> obj = list; // compile error
System.out.println(list);
}
}
Результат выполнения кода:
[abcde]
Пример
Давайте убедимся, что обратное присваивание
List<Object> в List<String>
также невозможно:
import java.util.List;
import java.util.ArrayList;
public class Main
{
public static void main(String[] args)
{
List<Object> list = new ArrayList<>();
list.add("abcde");
// List<String> str = list; // compile error
System.out.println(list);
}
}
Результат выполнения кода:
[abcde]
Пример
Давайте проверим, что массив, в отличие от
обобщённого списка, ковариантен - то есть
String[] можно присвоить в Object[]:
public class Main
{
public static void main(String[] args)
{
String[] arr = {"abcde", "12345"};
Object[] obj = arr;
System.out.println(obj[0]);
}
}
Результат выполнения кода:
"abcde"
Смотрите также
-
механизм
ковариантность,
который разрешает присваивание в сторону родителя -
механизм
контравариантность,
который разрешает присваивание в сторону потомка -
конструкция
wildcard,
которая позволяет обойти инвариантность -
конструкция
wildcard extends,
которая задаёт верхнюю границу типа