Jan Schultke Jan Schultke - 3 months ago 14
Java Question

Possible to avoid boxing and unboxing for Lambda using Class::method syntax? (Java)

I've recently stumbled upon the

Class::method
syntax which allows you to insert lambda code which from a static method like this:

public class Main {

public static void foo(int foo) {
System.out.println(foo);
}

public static void bar(Consumer<Integer> bar) {
bar.accept(1);
}

public static void main(String[] args) {
bar(Main::foo);
}

}


The question is, does boxing and unboxing of 1 still occur? After all,
bar
's parameter is a
Consumer<Integer>
which should normally box primitives, yet
foo(int)
is a method which accepts a primitive, thus boxing is not neccessary.

So, what happens? Does
1
get turned into an
Integer
or does it remain primitive?

On a side note, I am aware that
IntConsumer
delivers a solution to get rid of boxing and unboxing, but not every single functional interface has an alternative for every single primitive type, hence the question.

Answer

Yes it is boxed and then unboxed.

Compiling the code and then decompiling the class file reveals the following:

import java.util.function.Consumer;

public class Main {
    public Main() {
    }

    public static void foo(int foo) {
        System.out.println(foo);
    }

    public static void bar(Consumer<Integer> bar) {
        bar.accept(Integer.valueOf(1));
    }

    public static void main(String[] args) {
        bar(Main::foo);
    }
}

The compiler automatically boxes 1, meaning it will be unboxed when foo() is called.