为何Getter方法是Function而非Supplier?非静态方法是否隐含接收对象?
关于Java 8函数式接口与Getter方法引用的疑问解答
1. 链式调用Getter处理深层嵌套对象完全可行
针对你处理嵌套XML对象的需求,用函数式接口的链式调用完全可以实现深层属性获取。通过Function的andThen()方法,把多个Getter的方法引用串联起来,就能从顶层对象一路拿到最底层的嵌套属性。举个例子:
假设你有层级结构Country -> City -> Street,要从Country获取Street的名称,可以这么写:
Function<Country, City> getCityFromCountry = Country::getCity; Function<City, Street> getStreetFromCity = City::getStreet; Function<Country, String> getStreetNameFromCountry = getCityFromCountry.andThen(getStreetFromCity).andThen(Street::getName); // 调用时传入顶层Country对象即可 String streetName = getStreetNameFromCountry.apply(myCountry);
2. 为什么Getter是Function<City, String>?
这要从未绑定的实例方法引用的适配规则说起:
当你写City::getName这种类名+实例方法的引用时,它本质上需要一个City实例来调用该方法——这个实例会被当作函数的输入参数。换句话说,这个方法引用等价于Lambda表达式:
Function<City, String> getNameFunc = (City city) -> city.getName();
完全符合Function<T, R>的签名:接收一个T类型的参数(这里是City),返回R类型的结果(这里是String)。
3. 非静态方法是否总会接收所属对象作为参数?
是的,Java的实例方法在底层执行时,都会隐式把当前对象(this)作为第一个参数传递给方法——只是我们写代码的时候不需要显式声明。而方法引用的机制,就是把这个隐式的this参数变成了显式的函数输入参数,所以未绑定的实例方法引用才能适配成Function这类需要输入的函数式接口。
4. 为什么City::getName不是Supplier?
Supplier的签名是无参、返回一个值,它要求不需要任何输入就能产生结果。而City::getName是未绑定的方法引用——它还没有关联具体的City实例,必须传入一个City对象才能调用getName()。
只有当你把方法引用绑定到具体的实例时,它才会变成Supplier:
// 绑定到具体的City实例 City paris = new City("Paris"); Supplier<String> parisNameSupplier = paris::getName; // 调用时不需要传参,直接返回绑定实例的名称 String name = parisNameSupplier.get();
内容的提问来源于stack exchange,提问作者hellohellohello
相关产品推荐
相关产品推荐

