Java 未重写接口默认实现时编译失败
我正在尝试实现org.apache.spark.sql.Row。接口有几个方法的默认实现,IntelliJ不会抱怨没有覆盖这些方法。 但是,当使用maven构建时,我得到:Java 未重写接口默认实现时编译失败,java,scala,apache-spark-sql,maven-compiler-plugin,Java,Scala,Apache Spark Sql,Maven Compiler Plugin,我正在尝试实现org.apache.spark.sql.Row。接口有几个方法的默认实现,IntelliJ不会抱怨没有覆盖这些方法。 但是,当使用maven构建时,我得到: FunctionalRow is not abstract and does not override abstract method mkString(java.lang.String,java.lang.String,java.lang.String) in org.apache.spark.sql.Row 下面是类的
FunctionalRow is not abstract and does not override abstract method mkString(java.lang.String,java.lang.String,java.lang.String) in org.apache.spark.sql.Row
下面是类的实现:
import java.util.List;
import java.util.function.Supplier;
import org.apache.spark.sql.Row;
import scala.collection.JavaConverters;
import scala.collection.Seq;
public class FunctionalRow implements Row {
protected List<Supplier<Object>> suppliers;
public FunctionalRow(List<Supplier<Object>> suppliers) {
this.suppliers = suppliers;
}
@Override
public int length() {
return suppliers.size();
}
@Override
public Object get(int i) {
return suppliers.get(i).get();
}
@Override
public Row copy() {
return this;
}
@Override
public Seq<Object> toSeq() {
return JavaConverters.asScalaIteratorConverter(suppliers.stream().map(s -> s.get()).iterator()).asScala().toSeq();
}
}
import java.util.List;
导入java.util.function.Supplier;
导入org.apache.spark.sql.Row;
导入scala.collection.JavaConverters;
导入scala.collection.Seq;
公共类FunctionalRow实现行{
受保护的供应商名单;
公职人员流动(供应商名单){
这意味着供应商=供应商;
}
@凌驾
公共整数长度(){
返回供应商。大小();
}
@凌驾
公共对象get(int i){
返回供应商.get(i).get();
}
@凌驾
公用行副本(){
归还这个;
}
@凌驾
公开序号toSeq(){
返回JavaConverters.asscalateratorconverter(suppliers.stream().map(s->s.get()).iterator()).asScala().toSeq();
}
}
maven编译器插件设置:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
maven编译器插件
3.8.0
默认编译
编译
编译
1.8
1.8
UTF-8
默认测试编译
测试编译
测试编译
1.8
1.8
UTF-8
1.8
1.8
UTF-8
任何帮助都将不胜感激 我正在把我的评论变成一个答案,这样你就可以把这个问题标记为已回答 TL;DR:如果Scala traits是由早于2.12的Scala版本编译的,则不能在Java中使用默认的Scala traits实现。这里使用的Spark版本就是这种情况,因此失去了所有希望。 原因与Scala编译器如何编码特性以与JVM兼容(因此也与Java兼容)有关 在Java8之前,接口不允许提供默认实现。Scala traits基本上是具有默认实现的可堆叠接口,必须进行编码,它既有一个没有实现的接口,也有一个提供实现的抽象类。有关详细信息,请参阅
在Java8之后,接口被允许提供默认实现,因此Scala可以直接将默认实现的特性编码到Java接口,并与Java代码直接兼容。自Scala 2.12以来,Scala需要一个与Java 8+兼容的JVM,因此带来了traitinterface兼容性。如果Scala代码是由Scala 2.12+编译器编译的,您可以将它的特性用作普通Java接口。我将我的评论作为答案,这样您就可以将这个问题标记为已回答 TL;DR:如果Scala traits是由早于2.12的Scala版本编译的,则不能在Java中使用默认的Scala traits实现。这里使用的Spark版本就是这种情况,因此失去了所有希望。 原因与Scala编译器如何编码特性以与JVM兼容(因此也与Java兼容)有关 在Java8之前,接口不允许提供默认实现。Scala traits基本上是具有默认实现的可堆叠接口,必须进行编码,它既有一个没有实现的接口,也有一个提供实现的抽象类。有关详细信息,请参阅
在Java8之后,接口被允许提供默认实现,因此Scala可以直接将默认实现的特性编码到Java接口,并与Java代码直接兼容。自Scala 2.12以来,Scala需要一个与Java 8+兼容的JVM,因此带来了traitinterface兼容性。如果Scala代码是由Scala 2.12+编译器编译的,您可以使用它的特性作为普通Java接口。也许不能这样做?您使用的Spark版本是使用Scala 2.12或更高版本编译的吗?使用Scala 2.12,traits可以直接编译为Java接口。这是因为Java 8在接口中引入了默认实现,所以Scala 2.12(需要Java 8+)可以转换为接口,而不需要您在链接的答案中引用的复杂机制。我不是Java互操作专家,但是Java应该看到
mkString
的默认实现,如果它确实存在的话。所以2.12不是一个选项。。。升级spark将完全超出我的任务范围,所以我现在不得不接受这个限制。但是很高兴知道,谢谢!也许这是不可能的?您使用的Spark版本是使用Scala 2.12或更高版本编译的吗?使用Scala 2.12,traits可以直接编译为Java接口。这是因为Java 8在接口中引入了默认实现,所以Scala 2.12(需要Java 8+)可以转换为接口,而不需要您在链接的答案中引用的复杂机制。我不是Java互操作专家,但是Java应该看到mkString
的默认实现,如果它确实存在的话。所以2.12不是一个选项。。。升级spark将完全超出我的任务范围,所以我现在不得不接受这个限制。但是很高兴知道,谢谢!