Search code examples
javalambdaprimitive

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.


Solution

  • 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.