Ссылка на метод не компилируется - Integer::new

Почему это не компилируется?

Stream.generate(Integer::new(1)).limit(10);

Это дает ошибку

Синтаксическая ошибка в токене "новый", AssignmentOperator ожидается после этого токена

Конечно, я мог бы переписать это выражение в

Stream.generate(() -> new Integer(1)).limit(10);

но я хочу знать причину, по которой первое утверждение не работает...


person Klaus Schulz    schedule 14.07.2016    source источник
comment
Вы не можете предоставлять дополнительные аргументы для ссылок на методы. Поэтому вместо этого вы должны использовать лямбда-выражение. Но в любом случае использование конструктора Integer бессмысленно. Вы можете использовать Stream.generate( () -> 1)  -  person Holger    schedule 14.07.2016
comment
Поскольку Integer::new(1) не является допустимой ссылкой на метод/конструктор. JLS   -  person Flown    schedule 14.07.2016


Ответы (1)


Вы не можете явно передавать аргументы в ссылки на методы. Их можно передать только неявно.

Например, если у вас есть IntStream, вы можете mapToObj преобразовать его в Integer экземпляров, используя ссылку на метод конструктора public Integer(int value):

IntStream.of(1,1,1).mapToObj(Integer::new)...

Конечно, использование конструктора public Integer(int value) для небольших значений int обычно является плохой идеей, так как это может привести к созданию нескольких ненужных экземпляров, имеющих одно и то же значение int, вместо использования конструктора IntegerCache, который кэширует Integer экземпляров малых значений. (от -128 до 127).

person Eran    schedule 14.07.2016
comment
Или IntStream.of(1,1,1).boxed(), чтобы избежать создания устаревших экземпляров… - person Holger; 14.07.2016
comment
@Holger Да, я никогда не говорил, что этот код имеет смысл. Я только продемонстрировал, как можно вызвать конструктор Integer(int), используя ссылку на метод. - person Eran; 14.07.2016
comment
Я бы сказал, что использование либо автоматического упаковывания, либо явного Integer.valueOf должно быть предпочтительным способом, независимо от фактического значения int. Это правда, что только небольшие значения гарантированно кэшируются, но это не исключает кэширования остальных, а использование фабрики также подтверждает, что разработчик не делает никаких предположений об идентичности объекта, другими словами, обычно разрешает кэширование, независимо от того, произойдет или нет. Возможна даже оптимизация на стороне JVM, поскольку JVM знает об этом методе. - person Holger; 14.07.2016