【发布时间】:2018-07-26 16:50:01
【问题描述】:
我在尝试创建基于方法参数类型使用的自定义谓词引用时发现了一些奇怪的东西。
我有一个名为AffiliateLinkSubset 的对象,它有一个名为isGeneral 的布尔getter。当我尝试执行以下操作时:
Predicate<?> partitionPredicate = AffiliateLinkSubset::isGeneral;
我收到错误non-static method cannot be referenced from a static context。
但是当我将泛型类型AffiliateLinkSubset 分配给它工作的谓词时,这没什么特别的。但特别的是,以下内容也可以工作:
Predicate<AffiliateLinkSubset> partitionPredicate = affiliateLinkSubset::isGeneral;
Predicate<?> test = partitionPredicate;
IDE 没有给出任何错误!即使我有效地将相同的 lambda 分配给无类型谓词测试。这怎么可能?谓词会在运行时起作用吗?我认为它会因为在编译期间所有类型都被删除并替换为 Object 类型。这就是为什么我不明白为什么我不能为无类型谓词分配 lambda。谁能解释一下?
AffiliateLinkSubset是实际类的缩写,这里是:
import POJOs.PojoENUMS.LocalizedStorefront;
import java.util.Map;
import java.util.Set;
public class AffiliateLinkSubsetForStatisticsCalculation {
private Long id;
private String title;
private Double productValue;
private boolean general;
private Set<String> keywords;
private Map<String, Boolean> booleanKeywords;
private LocalizedStorefront localizedStorefront;
public AffiliateLinkSubsetForStatisticsCalculation(Long id, String title, Double productValue, boolean general, Set<String> keywords, Map<String, Boolean> booleanKeywords, LocalizedStorefront localizedStorefront) {
this.id = id;
this.title = title;
this.productValue = productValue;
this.general = general;
this.keywords = keywords;
this.booleanKeywords = booleanKeywords;
this.localizedStorefront = localizedStorefront;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Double getProductValue() {
return productValue;
}
public void setProductValue(Double productValue) {
this.productValue = productValue;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isGeneral() {
return general;
}
public void setGeneral(boolean general) {
this.general = general;
}
public Set<String> getKeywords() {
return keywords;
}
public void setKeywords(Set<String> keywords) {
this.keywords = keywords;
}
public Map<String, Boolean> getBooleanKeywords() {
return booleanKeywords;
}
public void setBooleanKeywords(Map<String, Boolean> booleanKeywords) {
this.booleanKeywords = booleanKeywords;
}
public LocalizedStorefront getLocalizedStorefront() {
return localizedStorefront;
}
public void setLocalizedStorefront(LocalizedStorefront localizedStorefront) {
this.localizedStorefront = localizedStorefront;
}
}
【问题讨论】:
-
请向我们展示
AffiliateLinkSubset类及其方法isGeneral。 -
没有一个方法是静态的
-
@Maurice
Predicate<?> p = ffiliateLinkSubset::isGeneral;工作吗? -
@Lino 它不是静态上下文,当 IDE 没有任何其他标准错误消息要显示时抛出此错误,它没有说明实际错误的性质。
ffiliateLinkSubset::isGeneral是一个方法引用,或者可以说是一个 lambda 缩写。在这里查看更多信息:dzone.com/articles/java-lambda-expressions-vs -
@Maurice 您可以选择从概念上将方法引用视为 lambda 表达式的语法糖,但 the code generated is not the same,并且方法引用不会“脱糖”变成一个 lambda。当您提供的代码使用方法引用而不是 lambda 时,在这篇文章的标题、正文和标签中使用“lambda”是错误的。将方法引用称为 lambda 是不正确且错误的。
标签: java generics lambda java-8 functional-interface