引用特定对象的实例方法

And*_*rey 8 java lambda java-8 method-reference

在下面的代码中,它在使用类名传递方法引用变量时起作用,但是当使用用户对象传递引用变量时会出现错误.

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public void printName() {
        System.out.println(name);
    }    
}


public class Main {
    public static void main(String[] args) {
        User u1 = new User("AAA");
        User u2 = new User("BBB");
        User u3 = new User("ZZZ");

        List<User> userList = Arrays.asList(u1, u2, u3);        

        userList.forEach(User::printName); // works
        userList.forEach(u1::printName); // compile error
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 13

userList.forEach期待Consumer<? extends User>- 换句话说,一种接受User引用并用它做某事的方法.

那可能是:

  • 接受User参数的静态方法,在这种情况下,参数将在每次迭代时使用列表中的相关元素填充:

    staticMethod(userFromList)
    
    Run Code Online (Sandbox Code Playgroud)
  • 接受一个User参数的实例方法(任何类),提供一个特定的实例来调用它 - 再次,该参数将填充相关元素:

    target.instanceMethod(userFromList)
    
    Run Code Online (Sandbox Code Playgroud)
  • 上的实例方法User参数,提供没有一个特定的实例,这种情况下,目标的方法调用的将是在每次迭代的列表中的相关元件:

    userFromList.instanceMethod()
    
    Run Code Online (Sandbox Code Playgroud)

因为你试图指定一个目标并且该方法没有任何参数,所以该forEach方法对每个元素都没有任何作用 - 它不能将它作为参数传递,因为该方法没有任何参数,并且它不能用它作为方法目标,因为你已经指定了一个.

您的工作代码显示了第三个示例.以下是另外两种方法,可以让您演示前两种方法:

public class UserPrinter {
    private final String name;

    public UserPrinter(String name) {
        this.name;
    }

    public static void staticPrintUser(User user) {
        // Assuming you add a User.getName() method
        System.out.println("staticPrintUser: " + user.getName());
    }

    public void instancePrintUser(User user) {
        System.out.println("instancePrintUser (instance " + name + "): "
            + user.getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

userList.forEach(UserPrinter::staticPrintUser);    // equivalent to
//userList.forEach(p -> UserPrinter.staticPrintUser(p));
UserPrinter printer = new UserPrinter("my printer");
userList.forEach(printer::instancePrintUser);      // equivalent to
//userList.forEach(p -> printer.instancePrintUser(p));
Run Code Online (Sandbox Code Playgroud)

如果你真的想要printUser同样打User三次,忽略User列表中的,你可以使用:

userList.forEach(ignored -> u1.printName());
Run Code Online (Sandbox Code Playgroud)