I have encountered a short time ago with a competitive answer better than mine that uses a quite new method reference to me as replacement of lambda.
Stream.generate(new AtomicInteger(1)::getAndIncrement)...
I looked the Oracle specifications about the Method references and there are defined 4 types:
- Reference to a static method
ContainingClass::staticMethodName
- Reference to an instance method of a particular object
containingObject::instanceMethodName
- Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
- Reference to a constructor
ClassName::new
I struggle with categorizing this one. I haven't found any question on SO or anything relevant explained in the docs. How would be this translated to an anonymous class?
My suspicion is:
IntStream.generate(new IntSupplier() {
AtomicInteger atom = new AtomicInteger(1);
@Override
public int getAsInt() {
return atom.getAndIncrement();
}
})....
... I don't understand how is this possible. At first sight, I would guess the expression is:
IntStream.generate(new IntSupplier() {
@Override
public int getAsInt() {
return new AtomicInteger(1).getAndIncrement();
}
})....
... yet this is nothing else than () -> new AtomicInteger(1).getAndIncrement()
.
Where is this kind of expression defined and how it exactly would be rewritten in the lambda/anonymous class?
It's simply the second type: a reference to a method of a specific object, there's no additional logic behind the curtain.
Well
new AtomicInteger(1)
returns an instance, so it's the second one. The exact details of how this is translated are implementation specific, but it's a single instance created and this is back-ed up by the JLS 15.13.3In plain english, the part before
::
is evaluated when it's declaration is first encountered.Your assumption how this is translated is almost correct, it's like generating an instance outside of the function itself and using that - since it is effectively final, this is permitted.
You can replace
with
i.e. this method reference falls into the second category of method references -
Reference to an instance method of a particular object
.You should note that the
AtomicInteger
instance creation is not part of the implementation of theIntSupplier
. The Java 7 equivalent would be:.