Ответ 1
?
in Main<?>
является заполнителем, который может быть любым типом во время привязки.
Каждый ?
, который вы пишете в источнике, может быть другого типа (упоминается в сообщениях об ошибках как capture#2-of ?
), поэтому вы не можете назначить выражение Main<?>
переменной любого выражаемого типа.
Алмазный оператор работает здесь, потому что его вывод типа запускается после захвата ?
– ваш Main<>
становится не Main<?>
, а Main<capture#1 of ?>
(предполагается, что Main<?>
вы назначили его capture#1
).
Другими словами, оператор алмаза является единственным синтаксисом, который может непосредственно указывать конкретный захват, так же как var
в С# является единственным синтаксисом, который может напрямую указывать анонимный тип. (обратите внимание, что разрешение перегрузки с помощью вывода типа метода также может быть разрешено для определенных захватов)
Что касается кода, new Main<?>()
(для любого захвата ?
) является сокращением для Main<? extends Object>
или, в вашем случае, Main<? extends Main<same ?>>
(компилятор автоматически сжимает ?
к ограничениям типа). Это становится ковариантным представлением Main<>
, где параметр типа может быть конвертирован только в Main<?>
(так как это может быть любой тип, поэтому вы не можете принять что-либо за пределами ограничения).
Обычно нет причин реально создавать такую вещь.