2

I came across this example:

package br.com.teste;

class HighTemp {
    private int hTemp;
    HighTemp(int ht) {
        hTemp = ht;
    }
    boolean sameTemp(HighTemp ht2) {
        return hTemp == ht2.hTemp;
    }
}

interface MyFunc152<T> {
    boolean func(T v1, T v2);
}

class InstanceMethWithObjectRefDemo {
    static <T> int counter(T[] vals, MyFunc152<T> f, T v) {
        int count = 0;
        for (int i = 0; i < vals.length; i++)
            if (f.func(vals[i], v)) count++;
        return count;
    }

    public static void main(String args[]) {
        int count;
        HighTemp[] weekDayHighs = { new HighTemp(89), new HighTemp(82), new HighTemp(90), new HighTemp(89) };

        count = counter(weekDayHighs, HighTemp::sameTemp, new HighTemp(89));
        System.out.println(count + " days had a same of 89");
    }
}

Why this works? Particularly the part where an method reference is passed to a function with an interface argument.

        count = counter(weekDayHighs, HighTemp::sameTemp, new HighTemp(89));

Why HighTemp::sameTemp is valid as MyFunc152 ? And why passing HighTemp::sameTemp does not generate a compile error if sameTemp is not static?

Thiago Sayão
  • 2,197
  • 3
  • 27
  • 41
  • 2
    This is using [Functional Interfaces](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#approach6) and [Method References](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html). – Aaron Jan 17 '18 at 15:58

1 Answers1

2

Well, you are passing to your counter method a HighTemp[], which means it expects an instance of MyFunc152<HighTemp> as the second argument.

Now, HighTemp::sameTemp is a method reference to a method with two HighTemp arguments (the first of them is implicit - the HighTemp instance the method will be called on) and a boolean return type. This is an exact match to the boolean func(HighTemp v1, HighTemp v2) method of the MyFunc152<HighTemp> functional interface.

Inside your counter method, when you call the functional interface method with f.func(vals[i], v), it is equivalent to calling vals[i].sameTemp(v).

Instead of passing the method reference HighTemp::sameTemp, you could have passed an equivalent lambda expression (HighTemp t1,HighTemp t2)->t1.sameTemp(t2) (or simply (t1,t2)->t1.sameTemp(t2)).

Eran
  • 387,369
  • 54
  • 702
  • 768