这是接口中的默认方法

This in a default method in interface

根据我的理解,lambda 的工作方式类似于创建匿名实例 class 并提供抽象方法的实现 - 请随时对此发表评论

我也一直在研究 Java 中的组合器模式,并被下面接口的和方法中的“this”弄糊涂了,据我所知,this 指的是当前实例一个class。当我在 and 方法中执行 System.out.println(this) 时,它会打印 combinatorpatttern.CustomerRegistrationValidator$$Lambda/0x0000000800067440@12f40c25,这对于 class 所指的内容没有意义。

public interface CustomerRegistrationValidator
        extends Function<Customer, ValidationResult> {
  
   static CustomerRegistrationValidator isEmailValid() {
        return customer -> {
            System.out.println("running email validation");
            return customer.getEmail().contains("@") ?
                    SUCCESS : EMAIL_NOT_VALID;
        };
    }

    static CustomerRegistrationValidator isPhoneNumberValid() {
        return customer -> customer.getPhoneNumber().startsWith("+0") ?
                SUCCESS : PHONE_NUMBER_NOT_VALID;
    }

    static CustomerRegistrationValidator isAnAdult() {
        return customer ->
                Period.between(customer.getDob(), LocalDate.now()).getYears() > 16 ?
                        SUCCESS : IS_NOT_AN_ADULT;
    }
    
    default CustomerRegistrationValidator and (CustomerRegistrationValidator other) {
        return customer -> {
            
            ValidationResult result = this.apply(customer);
            return result.equals(SUCCESS) ? other.apply(customer) : result;
        };
    }

    enum ValidationResult {
        SUCCESS,
        PHONE_NUMBER_NOT_VALID,
        EMAIL_NOT_VALID,
        IS_NOT_AN_ADULT
    }
}


public class Main {

    public static void main(String[] args) {
        Customer customer = new Customer(
                "Alice",
                "alice@gmail.com",
                "+0898787879878",
                LocalDate.of(2015, 1,1)
        );
        
        ValidationResult result = isEmailValid()
                .and(isPhoneNumberValid())
                .and(isAnAdult())
                .apply(customer);

        System.out.println(result);
    }
}

在第一个 and 调用中:

isEmailValid().and(isPhoneNumberValid())

this 引用 return 由 isEmailValid() 编辑的对象。

在第二个 and 调用中:

isEmailValid().and(isPhoneNumberValid()).and(isAnAdult())
                                         ^^^

this 引用由第一个 and 调用 return 编辑的对象。如果不是很清楚,你可以认为这是两个步骤:

CustomerRegistrationValidator isEmailAndPhoneValid = 
    isEmailValid().and(isPhoneNumberValid());

// "this" refers to "isEmailAndPhoneValid"
isEmailAndPhoneValid.and(isAnAdult());

您现在应该看到模式,即 this 指的是紧接在 and 之前的任何内容。它在 lambda 表达式中的事实并没有太大的区别。重要的是它所在的方法

那么 isEmailValid()and 编辑的对象 return 是什么?正如您从源代码中看到的那样,两者都被声明为 return 实现接口 CustomerRegistrationValidator 的 class 实例,因此这些 lambda 表达式必须计算为此类对象。这些对象的 class 是什么?好吧,它们是自动生成的,并且有这样的名字:

combinatorpatttern.CustomerRegistrationValidator$$Lambda/0x0000000800067440@12f40c25

因此当你打印 this.

时输出