代码之家  ›  专栏  ›  技术社区  ›  Nariman Esmaiely Fard

“V不是功能接口”错误

  •  3
  • Nariman Esmaiely Fard  · 技术社区  · 7 年前

    我正在基于本教程编写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 回复  |  直到 7 年前
        1
  •  2
  •   Holger    7 年前

    的定义 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 调用和方法引用。如果将显式类型用于 单音图

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

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