java为什么没有输入参数的方法可以用来替换函数<T,R>
对于以下代码段,在calculateOnShipments
中,一个参数接受一个函数,其中Shipment
作为输入Double
作为输出
Function<Shipment, Double> f
1)为什么可以使用Shipment::calculateWeight
调用它calculateWeight()
不接受任何参数,尽管它返回Double
public double calculateWeight()
2)我试图注释掉calculateWeight()
,但保留calculateWeight(Shipment s1)
,然后出现错误消息
"Cannot make a static reference to the non-static method calculateWeight(Shipment) from the type Shipment"
这是什么意思?为什么说是静态引用?在我评论calculateWeight()
之前,为什么没有错误消息
class Shipment {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Shipment> l = new ArrayList<Shipment>();
l.add(new Shipment());
l.add(new Shipment());
Shipment shipment1 = new Shipment();
// Using an anonymous class
List<Double> lw = shipment1.calculateOnShipments(l, Shipment::calculateWeight);
System.out.println(lw);//[0.0,0.0]
}
public double calculateWeight() {
double weight = 0;
// Calculate weight
return weight;
}
public double calculateWeight(Shipment s1) {
double weight = 1;
// Calculate weight
return weight;
}
public List<Double> calculateOnShipments(
List<Shipment> l, Function<Shipment, Double> f) {
List<Double> results = new ArrayList<>();
for (Shipment s : l) {
results.add(f.apply(s));
}
return results;
}
}
# 1 楼答案
可以使用方法引用调用它,因为方法引用表示调用
shipment
上的方法calculateWeight
的代码,该方法被接受为Function<Shipment, Double>
的输入。阅读以下内容,了解更多相关信息或者更进一步
现在,如果您已经理解了上面的lambda表示,那么如果没有
calculateWeight
方法调用,方法引用是不可能的,因为调用calculateWeight
方法需要一个装运,一个是实例,在该实例上调用该方法,另一个是传递给该方法作为参数。那可能是请注意,将方法转换为
static
,例如将导致推断方法引用以接受实例作为参数本身,并将作为:
其中
Shipment::calculateWeight
表示shipment -> calculateWeight(shipment)
# 2 楼答案
calculateWeight()
是类Shipment
上的一个非静态方法,因此在某种意义上,它采用类型为Shipment
的隐式this
参数。所以Shipment::calculateWeight
是一个接受这个参数的函数。(如果calculateWeight()
是一个非静态方法,或者如果您编写了shipment1::calculateWeight
而不是Shipment::calculateWeight
以便将实例烘焙到方法引用中,那么这将是一个没有参数的函数。)这是个好问题。潜在的问题是,就方法引用而言,
calculateWeight(Shipment s1)
需要两个参数:类型Shipment
的隐式this
参数(因为它是类Shipment
上的实例方法),以及类型Shipment
的显式s1
参数错误信息会很奇怪;本质上,编译器是在说“这不是一个静态方法,所以你需要给它一个实例”,意思是你可以写
shipment1::calculateWeight
而不是Shipment::calculateWeight
来指定应该调用它的实例