Здесь
.map(entry -> new FooDTO(entry))
вы всегда , вызывая
new FooDTO(AbstractFoo)
конструктор, который устанавливает this.isBar
в ложь.
Даже еслиобъект, удерживаемый entry
, имеет тип времени выполнения Bar
, переменная entry
имеет тип AbstractFoo
, поскольку она является частью Collection<? extends AbstractFoo>
, поэтому компилятор знает, что объект должен быть AbstractFoo
,но не знает, что это Bar
.Разрешение перегрузки работает с типом ссылки в типе компиляции, а не с типом объекта во время выполнения.
Если вы хотите проверить тип времени выполнения объекта, удерживаемого entry
,вместо типа переменной вы можете использовать
this.isBar = (f instanceof Bar);
при назначении для своего поля.Это проверит тип времени выполнения реального объекта, на который ссылается f
.
В вашем более простом случае
Bar b = new Bar();
FooDTO f = new FooDTO(b);
вызов конструктора преобразуется в new FooDTO(Bar)
, потому чтовы передаете ему ссылку типа Bar
.
Если вместо этого у вас было:
AbstractFoo b = new Bar();
FooDTO f = new FooDTO(b);
, то вызов конструктора разрешится в new FooDTO(AbstractFoo)
, потому что вы передадите ссылкутипа AbtractFoo
.