



Прежде всего, вы можете использовать оператор ромба, чтобы определить тип справа:
List<Object> list = new ArrayList<>();
Is there any case the type of variable and instance can be different?
Универсальные типы в Java стираются во время выполнения. Это означает, что пример не имеет универсального типа. Тип существует только во время компиляции для переменной.
Общие типы слева и справа не обязательно должны быть одинаковыми, но тогда вы должны использовать подстановочные знаки:
List<?> list = new ArrayList<Integer>();
List<? extends Number> list = new ArrayList<Integer>();
С помощью этих подстановочных знаков вы значительно ограничены в том, что еще можете делать с объектами. Например, вы можете только get или Number из List<? extends Number>, но вы не можете add новый Integer для него (потому что это мог быть List<Double>, насколько вы знаете).
Это по-прежнему полезно, если вы хотите написать методы, которые могут принимать списки определенного типа интерфейса:
boolean areAllPositive(List<? extends Number> numbers) { ... }
Не могли бы вы подробнее рассказать о подстановочных знаках в дженериках или дать полезную ссылку, на которую я могу сослаться?
Возможно, начнем с официального руководства: docs.oracle.com/javase/tutorial/java/generics/wildcards.html
Возможный дубликат Понижение в Java