19

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

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

我想用 JavaFunction和 Guava来改造这个接口Function,同时保持它的FunctionalInterface. 我以为我有完美的安排:

@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' 注释无效;Function<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);
}

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

4

1 回答 1

10

如评论中所述,它与 oracle 编译器一起编译得很好。这是一个日食错误。

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

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 编译器错误阻止将Function用作lambda 目标类型


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

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;
    }
}

让你Function扩展这个AdapterFunction

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

    R call(T input);

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

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

Function<String, Object> function = st -> st.toString();
于 2015-06-04T07:39:48.230 回答