Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type Inference in Method Reference

I recently put my hands on Java 8 and tried using Method References. I was trying different kinds of Method references and got stuck in the type "Reference to an Instance Method of an Arbitrary Object of a Particular Type".

String[] arr = {"First", "Second", "Third", "Fourth"};

Arrays.sort(arr, String::compareToIgnoreCase);

This works perfectly well. But when I try to refer a method of a user defined class through its type :

Demo2[] arr = {a, b};

Arrays.sort(arr, Demo2::compare);

This displays compile-time error as "Non-static method cannot be referenced from a static context".

Here's the Demo2 class :

public class Demo2 implements Comparator<Demo2> {
    Integer i;

    Demo2(Integer i1){
        i = i1;
    }

    public Integer getI() {
        return i;
    }

    @Override
    public int compare(Demo2 o1, Demo2 o2) {
        return o1.getI().compareTo(o2.getI());
    }
}
like image 379
Harshdeep Singh Avatar asked Apr 07 '26 03:04

Harshdeep Singh


1 Answers

As greg-449 pointed to you, your code has a bug.

By making a method reference like YourObjet::yourMethod you make a static reference to the method of the instance. So the method will be called for each object and thus the signature needs to be different than the earlier

A code that will compile will be of the following form :

Demo2[] demos = {a, b};
Arrays.sort(demos, Demo2::compareTo);

public class Demo2 {
    Integer i;

    Demo2(Integer i1){
        i = i1;
    }

    public Integer getI() {
        return i;
    }

    public int compareTo(Demo2 other) {
        return this.getI().compareTo(other.getI());
    }
}

But as RealSkeptic pointed out, this is not the correct way to implement and objet comparison. You should give the Arrays.sort method a comparator instead :

 Arrays.sort(demos, (obj1, obj2) -> obj1.getI().compareTo(obj2.getI()));
like image 112
loicmathieu Avatar answered Apr 08 '26 19:04

loicmathieu