为什么我传递给Arrays.sort的方法引用必须是静态的?

时间:2018-07-15 12:58:43

标签: java methods java-8

我是Java 8的新手。我正在尝试创建一个示例,以引用特定类型的任意对象的实例方法。

我有一个带有一个名称字段的人员类,并尝试对人员类的firstName字段上的人员对象数组进行排序。

public class Person{

    String firstName;

    public Person(String firstName) {
        super();
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public int compareByFirstName(Person p1, Person p2) {
        return p1.getFirstName().compareTo(p2.getFirstName());
    }

}

public class TestInstanceMethorRefArbObjSample {

    public static void main(String[] args) {
        TestInstanceMethorRefArbObjSample obj=new TestInstanceMethorRefArbObjSample();
        obj.personSorting();
    }

    private void personSorting() {
        Person[] personArr= {new Person("Jinesh"),new Person("Sejal"),new Person("Ashish")};
        Arrays.sort(personArr,Person::compareByFirstName);
    }
}

但是我在下一行面临编译问题。

Arrays.sort(personArr,Person::compareByFirstName);
  

1。Person类型未定义适用的compareByFirstName(T,T)   这里TestInstanceMethorRefArbObjSample.java / InstaceMethodArbitaryObjectProject / src / com / methodreference / instancemethodrefarbitary /客户端行   11 Java问题   2.类型Person没有定义适用的compareByFirstName(T,T)   这里TestInstanceMethorRefArbObjSample.java / InstaceMethodArbitaryObjectProject / src / com / methodreference / instancemethodrefarbitary /客户端行   11 Java问题

我只是试图通过int compare(T o1,T o2)的实现;使用Person类的compareByFirstname。

一旦我将Person类的compareByFirstname方法更改为静态方法,一切就可以正常工作。

为什么需要将compareByFirstname更改为静态方法才能使其正常工作?

2 个答案:

答案 0 :(得分:3)

某些背景

Arrays.sort需要一个Comparator,当传递方法引用时,它必须是一种接受两个适当类型实例的方法。

创建这种方法有两种方法:

  1. any 类中创建一个 static 方法,该方法接受适当类型的两个参数。这基本上就是您所做的。这样的方法不需要在特定的类中声明,您还可以使用其他一些提供此类帮助方法的类。

您的编译器将确保生成的Comparator实例使用要比较的2个实例调用引用的方法。

  1. 该类型的特定类中创建一个 instance 方法,该方法接受适当类型的一个参数。

您的编译器将确保生成的Comparator实例以第2个实例为参数调用第一个实例上的引用方法。

您的具体情况

由于您的方法采用了两个参数,因此它必须是静态的,否则它将需要一个 third 实例才能运行。要么声明为静态,要么删除一个参数并实现 this 与参数之间的比较。

答案 1 :(得分:1)

您正在使用方法引用,并且由于您将其编写为Person::compareByFirstName,因此它引用的是静态方法。如果要引用实例方法,则需要先创建对象的实例,然后再用实例引用该方法,就像这样:

Person p = new Person("");
p::compareByFirstName

但是,这不是您要执行的操作,因为compare方法不是特定于实例的。

您可以通过将对象实例与另一个对象进行比较来更改比较方法以使其特定于实例

public int compareByFirstName(Person p2) {
    return this.getFirstName().compareTo(p2.getFirstName());
}

在这种情况下,您可以使用方法引用Person::compareByFirstName,因为比较变得无用。