Community
Participate
Working Groups
See code below. If "bar" is inlined, the resulting code is all messed up -- it thinks it needs to create arrays of the arguments: ******** BEFORE INLINE ********* class Foo { public void foo() { bar("b"); bar(); } public void bar(Object... args) { baz(args); } public void baz(Object... args) { System.out.println(args); } } ******** AFTER INLINE ******** class Foo { public void foo() { Object[] args = { "b" }; baz(args); Object[] args1 = {}; baz(args1); } public void baz(Object... args) { System.out.println(args); } }
I don't know if you can call it all messed up. Agreed, we can do it with out the array. Just having a quick glance at CallInliner, this may be the intended behavior but I don't know what the reason could be.
The refactoring is correct, since the invocation of the varargs method 'bar' implicitly creates the array. In this special case where bar's args is not used for anything else and is directly passed to another varargs method (at most once), we could be smarter and avoid the array creation. Small deviations from this special case already require the array variable (e.g. calling 'baz(args)' twice or accessing 'args.length').
I apologize for the sloppy "all messed up" remark (since it's functionally equivalent). I should have said it violates the principle of least astonishment, in this particular case. Thanks for looking into it. I also forgot the expected output: ******** EXPECTED AFTER INLINE ******** class Foo { public void foo() { baz("b"); baz(); } public void baz(Object... args) { System.out.println(args); } }