Мне трудно понять следующий код о двух объектах Predicate
. Первый использует подстановочный знак с нижней границей, второй — с верхней границей.
Predicate<? super String> p1 = s -> s.startsWith("a"); // why can I call startsWith()?
Predicate<? extends String> p2 = s -> s.startsWith("a");
p1.test("a"); // works
p2.test("a"); // doesn't work (why?)
Чего я не понимаю в p1
, так это почему можно вызывать методы из класса String
, например. startsWith()
? Почему я могу передавать только объекты String
в p1.test()
, я ожидал, что смогу вызвать его и для объектов Number
и Object
.
Как ведет себя p1
, я думал, что p2
будет, но это не так. Я даже не могу передать объект String
в p2.test()
. Для меня это не имеет смысла, потому что мы ожидаем объект, который наследуется от String
(включая String
).
Я думаю, что это как-то связано с тем, что мы указываем тип ссылки, а не тип самого объекта. Но какой тип тогда используется для объекта?