S1612 recommends to turn a lambda into a method reference, even if the result is not equivalent

Version: SonarLint for Eclipse with Eclipse 2021-09.

The rule “Lambdas should be replaced with method references” (java:S1612) already seems to have had some false-positives like this in the past that were subsequently fixed, but this variant still seems to be present in the latest version.

The issue can be reproduced with this short example:

import java.util.Date;
import java.util.function.Supplier;

public class LambdaTest
  public static class DateGetter
    public Date getDate()
      return null;

  public void method( Supplier<Date> supplier )
    System.out.println( "Hello World!" );

  public static void main( String[] args )
    DateGetter[] i = new DateGetter[] {}; // empty array
    LambdaTest lt = new LambdaTest();

    // False-Positive: rule S1612 recommends to replace this...
    lt.method( () -> i[0].getDate() ); // works fine if the lambda is never used by the method().
    // ...with this...
    lt.method( i[0]::getDate ); // immediately throws IndexOutOfBoundsException.

In this case () -> i[0].getDate() is not equivalent to i[0]::getDate. The second case is first accessing the array, taking the first element and then effectively producing a method reference that is more equivalent to elem -> elem.getDate(). If the array is not populated at that index, this can actually fail.
(Unfortunately even Eclipse’s quick fix offers to turn the lambda into a method reference like this, despite the side effect.)

Note that if you actually replace i[0] with a getter for the DateGetter instance, rule S1612 already seems to have a case for that and will not recommend to replace the lambda with a method reference. Which makes me believe that showing it for this array access is just an oversight.

1 Like

Hello, @CrushaKRool.

Thanks for this very useful feedback. We will look at this and keep you posted in this topic.
Have a good day!