Java 忽略导入库中的默认接口方法并将它们视为抽象

Posted

技术标签:

【中文标题】Java 忽略导入库中的默认接口方法并将它们视为抽象【英文标题】:Java ignores default interface methods in an imported library and treats them as abstract 【发布时间】:2021-06-16 10:25:25 【问题描述】:

我正在尝试使用 Functional Java 库。

我只是将它包含在build.gradle

dependencies 
    compile "org.functionaljava:functionaljava:4.8.1"

并使用openjdk-15 进行编译,它就可以正常工作......大部分时间。

我遇到的问题如下:

我需要实现一个interface (fj.Ord.Definition),它应该是一个函数式接口——它有一个非default 方法和许多default 方法。

这意味着通过 lambda 实现,或者 this

new Ord.Definition<MyClass>() 
    @Override
    public F<MyClass, Ordering> compare(MyClass a) 
        return b -> a.myCompare(b);
    

应该没问题。

我得到的是:

Intellij:“类'从定义派生的匿名类'必须声明为抽象或在'定义'中实现抽象方法'比较(A,A)'”

如果我还是尝试编译它,javacerror: &lt;anonymous MyClass$1&gt; is not abstract and does not override abstract method ord()

这当然不仅适用于 ord,还适用于其他 11 个 default 方法。

如果我尝试用Ord.Definition.super 来实现它们

@Override
public F<A, A> prepend(A a1) 
    return Ord.Definition.super(a1);

我收到错误 'java.lang.Object' is not an inner class

这里要注意的是,在我的项目中从 Intellij 查看时,functionaljava 库源代码充满了这些类型的错误(以及更多错误)。 Intellij 抱怨类型变量和Object 之间的各种不匹配的错误也很常见。

所以我的问题是:

    如何按照库的意图(或至少通过使用其 default 方法)将 Ord.Definition 实现为 lambda? 什么允许编译该库,尽管它包含多少明显错误?

EDIT1:根据请求,这里是引用的fj.Ord.Definition 接口的一些块:

/**
 * Tests for ordering between two objects.
 *
 * @version %build.number%
 */
public final class Ord<A> 

  /**
   * Primitives functions of Ord: minimal definition and overridable methods.
   */
  public interface Definition<A> extends Equal.Definition<A>, Semigroup.Definition<A> 

    F<A, Ordering> compare(A a);

    default Ordering compare(A a1, A a2) 
      return compare(a1).f(a2);
    

    // equal:
    @Override
    default boolean equal(A a1, A a2) 
      return compare(a1, a2) == Ordering.EQ;
    

...

    @Override
    default F<A, A> prepend(A a1) 
      return apply((a2, o) -> o == Ordering.GT ? a1 : a2, compare(a1));
    

...

    /**
     * Build an ord instance from this definition.
     * to be called after some successive @link #then(F, Ord) calls.
     */
    default Ord<A> ord() 
      return ordDef(this);
    
  

...

EDIT2:事实证明,在这种情况下,我可以通过使用 fj.Ord#ord(fj.F&lt;A,fj.F&lt;A,fj.Ordering&gt;&gt;)fj.Ord#ord(fj.F2&lt;A,A,fj.Ordering&gt;) 方法创建排序来回避这个问题,每个方法都会产生一个 Ord&lt;A&gt;。然而,这并不能回答我提出的问题。

【问题讨论】:

显示Ord.Definition的代码 我链接到它。又来了:github.com/functionaljava/functionaljava/blob/… 链接最终会腐烂,或者链接代码的变化足以使您的问题对未来的读者无效。您应该包含足够多的代码以使问题独立。 【参考方案1】:

您使用了错误的依赖项。 org.functionaljava:functionaljava 被改造为在 Java 7 上工作(根据项目文档为 6)。您需要改用org.functionaljava:functionaljava-java8

dependencies 
    implementation "org.functionaljava:functionaljava-java8:4.8.1"

【讨论】:

你是对的。谢谢你。 (我之前尝试过同时包含functionaljavafunctionaljava-java8,但没想过只包含functionaljava-java8。)

以上是关于Java 忽略导入库中的默认接口方法并将它们视为抽象的主要内容,如果未能解决你的问题,请参考以下文章

Java8新特性——接口中的默认方法和静态方法

Java8新特性——接口中的默认方法和静态方法

java中为什么接口中的属性和方法都默认为public?

如何使用 JSFL 将不同文件夹中的大量位图导入到库中,并将文件夹结构保存在 fla 文件中

尝试访问导入库中的方法时,Android Studio 显示“无法解析符号”

Storybook Angular:如何使用导入的自定义库中的模型/接口?