Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method reference in Java 8

public class Car {

    private int maxSpeed;

    public Car(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }
}

We can sort a list of cars by,

    Car carX = new Car(155);
    Car carY = new Car(140);

    List<Car> cars = new ArrayList<>();
    cars.add(carX);
    cars.add(carY);

    cars.sort(Comparator.comparing(Car::getMaxSpeed));

If we see the signature of the method Comparator.comparing, the input parameter type is Function<? super T, ? extends U>

In the above example, how is Car::getMaxSpeed being cast to Function<? super T, ? extends U> while the following does not compile?

  Function<Void, Integer> function = Car::getMaxSpeed;
like image 389
saravana_pc Avatar asked Jun 03 '16 15:06

saravana_pc


People also ask

What is the method reference in Java 8?

Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

What is the benefit of using method reference in Java 8?

Method Reference in java 8 makes the code simple and more readable than lambda expression. Method reference refers to the method via the use of an :: operator. A method reference in Java 8 can execute only a single method call like a lambda expression but a shorter code.

What is method reference and constructor references in Java 8?

A method reference is similar to lambda expression used to refer a method without invoking it while constructor reference used to refer to the constructor without instantiating the named class. A method reference requires a target type similar to lambda expressions.


1 Answers

The assignment:

Function<Void, Integer> function = carX::getMaxSpeed;

does not compile because it's a Supplier<Integer>, not a Function.

So then, why does this compile?:

Comparator.comparing(Car::getMaxSpeed)

Java 8 allows an instance method reference that is a Supplier<U> to be provided where a Function<T, U> is expected, and the compiler effectively converts the getter method into a function.

To find out why this is possible, let's look at how we invoke a getter method using reflection:

System.out.println(Car.class.getMethod("getMaxSpeed").invoke(carX)); // "155"

When calling invoke() on an instance method, we pass the instance to the invoke() method of the getter's Method - there's an implied parameter of the instance type. When looked at it this way, we see that under the hood a getter is really implemented as a Function<T, U> via the invoke() method.

like image 76
Bohemian Avatar answered Oct 12 '22 00:10

Bohemian