功能接口继承怪癖

我有一个自定义界面,我已经使用了一段时间,看起来像这样:

public interface Function<T, R> {
    R call(T input);
}

我想用Java的函数和Guava的函数来改造这个界面,同时保持它的FunctionEntInterface。我以为我有完美的安排:

@FunctionalInterface
public interface Function<T, R> extends
        java.util.function.Function<T, R>,
        com.google.common.base.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}

两个超接口都声明了相同的方法,该方法已在我的接口中实现,只留下抽象方法。奇怪的是,它不会编译,告诉我apply()call()

无效的“@FunctionalInterface”注释;功能<T,R>不是功能接口

更奇怪的是,以下变体编译得很好:

@FunctionalInterface
public interface Function<T, R> extends
        java.util.function.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}

@FunctionalInterface
public interface Function<T, R> extends
        com.google.common.base.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}

public interface Function<T, R> extends
        java.util.function.Function<T, R>,
        com.google.common.base.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}

@FunctionalInterface
public interface Function<T, R> extends
        java.util.function.Function<T, R>,
        com.google.common.base.Function<T, R> {

    @Override
    R apply(T input);
}

第一个版本无法编译是有原因的吗?


答案 1

如注释中所述,它使用oracle编译器编译良好。这是一个日食虫。

等待错误修复,我个人将删除注释(您的第3个变体):@FunctionalInterface

public interface Function<T, R>
                                extends
                                    java.util.function.Function<T, R>,
                                    com.google.common.base.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}

此解决方案的主要不便之处在于 eclipse 编译器 bug 阻止将 用作 lambda 目标类型Function


如果你真的想继续你的,一个(丑陋的)解决方法可能是引入一个中间接口:@FunctionalInterfaceFunction

public interface AdapterFunction<T, R>
                                      extends
                                          java.util.function.Function<T, R>,
                                          com.google.common.base.Function<T, R> {
    @Override
    default R apply(T input) {
        return null;
    }
}

并让你扩展这个:FunctionAdapterFunction

@FunctionalInterface
public interface Function<T, R>
                                extends
                                    AdapterFunction<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}

在这种情况下,它也是 eclipse 的有效目标类型:Function

Function<String, Object> function = st -> st.toString();

答案 2

推荐