Function<Integer, Integer> add = (a,b) -> a+b;
You're confused; this does not compile. a Function<Integer, Integer> turns one integer reference into another; what you've written turns two references into another. I assume you meant e.g:
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
Is auto-boxing involved here?
Yes.
I know that auto-boxing can be a performance isse because it creates an Object each time (instead of a primitive on the stack) This can be frustrating if it happens implicitly, so i ask ;)
You've forgotten about the golden rule of performance.
Your puny human brain cannot fathom the depths and interactions that occur here. That's not me insulting you: That's the gist that even the engineers that work on the JVM's optimization routines themselves openly advocate: Between CPU caches, pipelines, OS optimizations, specter rewrites, and hotspot - you have no idea.
There are only 2 reasonable positions to take when looking at code and pointing at it to say: This is inefficient and it should be rewritten.
You look at the algorithm and realize that the algorithm's complexity is needlessly complicated. For example, you look at some sorting code and realize it's bubble sort instead of the more optimal quicksort (i.e. that an O(n log n) algorithm is available but the code you're looking at is worse than that).
You have a profiler report and some results based on plausible realistic data that says both: We have a performance issue, and this is the 1% of code that the CPU is spending 99% of its time on.
Anything else, such as this casual 'I heard autoboxing was bad'? A grave mistake. Do not rewrite code for reasons like this. You're saving usually literally 0 nanoseconds of performance. When you really are faced with a performance issue and a profiler report that tells you which 1% of the code you need to look at, you usually need to rewrite parts, and that means you want all code in the project to be neat, flexible, easy to test, and abstract enough to make it easy to e.g. retype the data that flows into and out of that crucial path your profiler told you about. Usually, 'rewrite because some performance moronic guide said so' makes your code less abstract and less flexible, and in that way it harms performance. Because it'll be harder to rewrite the crucial path if it comes up, and rewriting the crucial path is the only change to the code base that has a meaningful impact on performance.
If yes, how to avoid autoboxing (and still have something similar to fkt-pointers?)
BiFunction is not the right type. For starters, this feels more like an Operator (the difference is, a function can e.g. turn an integer and a string into an inputstream, an operator operates only on the same types: All integers, for example). There are specialized cases of the functional interfaces for some of the primitives.
Thus, what you really want then perhaps, is:
IntBinaryOperator add = (a, b) -> a + b;