Метод Container.add
- это метод экземпляра, для которого требуется вызвать экземпляр. Поскольку ссылка метода на форму ClassName::methodName
не связана с экземпляром, Container::add
имеет функциональную подпись (Container<T>,T)
.
Как вы не указали аргументы типа для Container
или целевого типа, компилятор выберет Container<Object>
. Таким образом, Container::add
имеет следующую форму: (Container<Object>,Object)
, что подходит для accept
метода ObjIntConsumer<Container<Object>>
, который имеет подпись (Container<Object>,int)
.
Второй аргумент может принимать значение типа int
, так как, после того, как бокс его Integer
, это присваиваемые Object
.
Те же работы, если присвоить результат переменной, обеспечивая тем самым целевой тип, из Container<Object>
или Container<Integer>
как
Container<Integer> collected
= IntStream.of(2, 3, 1).collect(Container::new, Container::add, null);
Любой тип аргумента, который может потреблять Integer
, например, Serializable
или Number
, также будет работать.
Вы можете прочитать больше о неограниченных ссылок на методы экземпляра в “What does ‘an Arbitrary Object of a Particular Type’ mean in java 8?”.
В качестве примечания, то collect
методов потоков не должны принимать null
аргументов и Stream
реализации не делает. Прохождение null
работает с примитивными потоками - это сбой в текущей реализации, и код, который проходит null
, скорее всего, сломается в следующей версии. Как Tagir Valeev pointed out, поведение уже changed в текущем состоянии развития Java 9.
Кстати, я удивлен, что 'IntStream' принимает' null' в качестве последнего аргумента 'collect'. Стандартная реализация «Stream» не работает. – Holger
Это [уже исправлено] (http://hg.openjdk.java.net/jdk9/dev/jdk/diff/013baa71b58b/src/share/classes/java/util/stream/IntPipeline.java) в JDK-9, таким образом, я бы не писал это так –
Мое замешательство не связано с боксом, распаковкой. Я предоставляю метод с одним аргументом «add (T t)», но он преобразуется в 2 аргумента accept (T t, int value). Я ожидаю что-то вроде этого: Требуется: java.lang.Integer найдено: java.lang.Integer, int Причина: фактические и формальные списки аргументов различаются по длине –