“V不是功能界面”错误

时间:2017-10-27 14:23:23

标签: java elasticsearch java-8

我正在编写一个基于本教程的elasticsearch插件: Creating an elasticsearch plugin, the basics

这里我得到“V不是功能界面”错误:

@Override
    public Map<String, AnalysisModule.AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
        return Collections.singletonMap("jettro", MyTokenFilterFactory::new);
    }

MyTokenFilterFactory的代码:

public class MyTokenFilterFactory extends AbstractTokenFilterFactory {

public MyTokenFilterFactory(IndexSettings indexSettings, String name, Settings settings) {
    super(indexSettings, name, settings);
}

@Override
public TokenStream create(TokenStream tokenStream) {
    return new TokenFilter(tokenStream);
}

1 个答案:

答案 0 :(得分:2)

AnalysisModule.AnalysisProvider的定义是

public interface AnalysisProvider<T> {
    T get(IndexSettings indexSettings, Environment environment,
          String name, Settings settings) throws IOException;
    // irrelevant default methods omitted
}

要通过方法引用将构造函数绑定到此接口,它必须具有完全相同的签名,即您必须将声明更改为

public class MyTokenFilterFactory extends AbstractTokenFilterFactory {

    public MyTokenFilterFactory(IndexSettings indexSettings, Environment environment,
                                String name, Settings settings) {
        super(indexSettings, name, settings);
    }

    @Override
    public TokenStream create(TokenStream tokenStream) {
        return new TokenFilter(tokenStream);
    }
}

忽略该附加参数。如果您不希望普通调用者提供不需要的参数,则可以重载构造函数

public class MyTokenFilterFactory extends AbstractTokenFilterFactory {

    public MyTokenFilterFactory(IndexSettings indexSettings, Environment environment,
                                String name, Settings settings) {
        super(indexSettings, name, settings);
    }
    public MyTokenFilterFactory(IndexSettings indexSettings,
                                String name, Settings settings) {
        super(indexSettings, name, settings);
    }

    @Override
    public TokenStream create(TokenStream tokenStream) {
        return new TokenFilter(tokenStream);
    }
}

或者您只保留原始构造函数,仅声明所需的参数并将方法引用更改为lambda表达式:

public Map<String, AnalysisModule.AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
    return Collections.singletonMap("jettro",
                                    (is, env, n, s) -> new MyTokenFilterFactory(is, n, s));
}

请注意,误导性编译器错误消息很可能是由于singletonMap调用的类型推断与方法引用之间的复杂交互。如果对singletonMap调用使用显式类型,即

public Map<String, AnalysisModule.AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
    return Collections.
        <String, AnalysisModule.AnalysisProvider<TokenFilterFactory>>
        singletonMap("jettro", MyTokenFilterFactory::new);
}

您将立即收到有关不匹配构造函数签名的有意义的错误消息。作为一般经验法则,如果使用较新的Java语言结构获得奇怪的错误消息,请尝试插入显式类型,直到获得可理解的错误消息。解决问题后,您可以再次删除当时不必要的显式类型。