Java 忽略导入库中的默认接口方法并将它们视为抽象方法
Java ignores default interface methods in an imported library and treats them as abstract
我正在尝试使用 Functional Java 库。
我只是将它包含在 build.gradle
和
中
dependencies {
compile "org.functionaljava:functionaljava:4.8.1"
}
并使用 openjdk-15
进行编译,它就可以正常工作...大部分。
我遇到的问题如下:
我需要实现一个 interface
(fj.Ord.Definition
),它应该是一个函数式接口——它有一个非 default
方法和许多 default
方法。
这意味着通过 lambda 的实现,或者这个
new Ord.Definition<MyClass>() {
@Override
public F<MyClass, Ordering> compare(MyClass a) {
return b -> a.myCompare(b);
}
}
应该没问题。
我得到的是:
Intellij:“Class 'Anonymous class derived from Definition' 必须声明为抽象方法或在 'Definition' 中实现抽象方法 'compare(A, A)'”。 =39=]
如果我仍然尝试编译它,javac: error: <anonymous MyClass> 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
之间的各种不匹配的错误在那里也很常见。
所以我的问题是:
- 我怎样才能将
Ord.Definition
实现为 lambda,正如库打算的那样(或者至少通过使用它的 default
方法)?
- 是什么允许该库在包含多少明显错误的情况下进行编译?
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<A,fj.F<A,fj.Ordering>>)
或 fj.Ord#ord(fj.F2<A,A,fj.Ordering>)
创建我的排序来回避这个问题,每个产生一个 Ord<A>
。然而,这并没有回答我提出的问题。
您使用了错误的依赖项。 org.functionaljava:functionaljava
进行了改造以在 Java 7 上工作(根据项目文档,还有 6 个)。您需要使用 org.functionaljava:functionaljava-java8
代替:
dependencies {
implementation "org.functionaljava:functionaljava-java8:4.8.1"
}
我正在尝试使用 Functional Java 库。
我只是将它包含在 build.gradle
和
dependencies {
compile "org.functionaljava:functionaljava:4.8.1"
}
并使用 openjdk-15
进行编译,它就可以正常工作...大部分。
我遇到的问题如下:
我需要实现一个 interface
(fj.Ord.Definition
),它应该是一个函数式接口——它有一个非 default
方法和许多 default
方法。
这意味着通过 lambda 的实现,或者这个
new Ord.Definition<MyClass>() {
@Override
public F<MyClass, Ordering> compare(MyClass a) {
return b -> a.myCompare(b);
}
}
应该没问题。
我得到的是:
Intellij:“Class 'Anonymous class derived from Definition' 必须声明为抽象方法或在 'Definition' 中实现抽象方法 'compare(A, A)'”。 =39=]
如果我仍然尝试编译它,javac: error: <anonymous MyClass> 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
之间的各种不匹配的错误在那里也很常见。
所以我的问题是:
- 我怎样才能将
Ord.Definition
实现为 lambda,正如库打算的那样(或者至少通过使用它的default
方法)? - 是什么允许该库在包含多少明显错误的情况下进行编译?
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<A,fj.F<A,fj.Ordering>>)
或 fj.Ord#ord(fj.F2<A,A,fj.Ordering>)
创建我的排序来回避这个问题,每个产生一个 Ord<A>
。然而,这并没有回答我提出的问题。
您使用了错误的依赖项。 org.functionaljava:functionaljava
进行了改造以在 Java 7 上工作(根据项目文档,还有 6 个)。您需要使用 org.functionaljava:functionaljava-java8
代替:
dependencies {
implementation "org.functionaljava:functionaljava-java8:4.8.1"
}