I grok that for capturing lambdas, there needs to be an object allocated (be it Object[]
or some abc$Lambda$xyz
type). Is it possible to customize this process anyhow? Let's say I have this code:
private void test() {
int x = 5;
Supplier<Integer> supplier = () -> x;
foo(supplier); // potentially passes the supplier to another thread etc.
}
and I don't want to allocate the object capturing x
, but instead just get it from a pool and fill in the value; I also know that at some point I can return the object to the pool.
I could write
Supplier<Integer> supplier = pool.get(x, v -> v);
and I could have specialized versions for different argument types (as using Object...
would do the allocation (ok, there's a chance that the allocation would be eliminated by escape analysis...) but that would render the code quite unreadable. Therefore I am looking for a more aspect-like way.
Is such thing possible?
EDIT: to make the pool's functionality more obvious, the get
could be implemented as
class IntHolderSupplier implements Supplier<Integer> {
int value;
IntFunction<Integer> func;
@Override public Integer get() {
return func.apply(value);
}
}
class Pool {
Supplier<Integer> get(int arg, IntFunction<Integer> func) {
IntHolderSupplier holder = ...;
holder.value = arg;
holder.func = func;
return holder;
}
}
and I would need such holder with specific signatures for all possible types lambdas I want to use.
Maybe I have complicated the example a bit by providing the function - but I wanted to capture the fact that there may be a additional computation applied to the captured argument at time of Supplier.get()
invocation.
And please ignore the fact that the int is boxed which can produce an allocation.