[英]Scala Function1<T,U> becomes Function1<Object,Object> in Java
I am trying to use the Deequ library from Java, and am having issue using the following method:我正在尝试使用 Java 中的 Deequ 库,但使用以下方法时遇到问题:
def hasCompleteness(
column: String,
assertion: Double => Boolean,
hint: Option[String] = None)
: CheckWithLastConstraintFilterable = {
addFilterableConstraint { filter => completenessConstraint(column, assertion, filter, hint) }
}
In particular, for the assertion, I need to pass in a Function1<Double, Boolean>
特别是,对于断言,我需要传入一个
Function1<Double, Boolean>
So I use the following code to create an assertion function in Java:所以我使用下面的代码在Java中创建一个断言function:
public static Function1<Double, Boolean> atLeast(double thresholdPercentage) {
return new scala.compat.java8.functionConverterImpls.FromJavaFunction<>((Double actualPercentage) -> actualPercentage >= thresholdPercentage);
}
Simple enough, right?很简单,对吧?
Only, my Java Class now won't compile because the signature of the hasCompleteness
method, when viewed from Java is that the assertion parameter is a Function1<Object, Object>
.只是,我的 Java Class 现在无法编译,因为
hasCompleteness
方法的签名,从 Java来看,断言参数是一个Function1<Object, Object>
。 Thus I see the following error:因此,我看到以下错误:
Required type: Function1<Object, Object>
Provided: Function1<Double, Boolean>
If I change my atLeast
method to return an unparametrized Function1
the issue goes away, but this feels like an ugly kludge.如果我更改我的
atLeast
方法以返回未参数化的Function1
问题就会消失,但这感觉就像一个丑陋的杂物。
Am I condemned to losing the type params when using this method from Java?使用 Java 中的这种方法时,我是否注定会丢失类型参数? Or is there something perhaps wrong with my IntelliJ / Gradle setup causing this weird behavior?
还是我的 IntelliJ / Gradle 设置可能有问题导致这种奇怪的行为?
That seems how Scala compiler translates "primitive" Scala types (remember, Double
here is scala.Double
and not java.lang.Double
). That seems how Scala compiler translates "primitive" Scala types (remember,
Double
here is scala.Double
and not java.lang.Double
). Eg Scala declarations例如 Scala 声明
var d: Double => Boolean;
var s: String => String;
produce (as shown by javap):产生(如javap所示):
public abstract scala.Function1<java.lang.Object, java.lang.Object> d();
public abstract scala.Function1<java.lang.String, java.lang.String> s();
Note how Double
and Boolean
both translate to Object
, but String
is preserved请注意如何
Double
和Boolean
都转换为Object
,但String
被保留
peterz detailed exactly what happens under the hood.彼得兹详细描述了幕后发生的事情。
Sounds like what you need is an explicit conversion from the primitive double
Java predicate ( java.util.function.DoublePredicate
) to the scala.Double
Scala predicate ( Double => Boolean
). Sounds like what you need is an explicit conversion from the primitive
double
Java predicate ( java.util.function.DoublePredicate
) to the scala.Double
Scala predicate ( Double => Boolean
).
Scala actually offers one such conversion called FromJavaDoublePredicate
. Scala 实际上提供了一种称为
FromJavaDoublePredicate
的转换。 The code does not require explicit Double
cast anymore:该代码不再需要显式
Double
强制转换:
/* some scala file */
def hasCompleteness(
x: Double,
f: Double => Boolean
): Unit = println(f(x))
/* some java file */
public static FromJavaDoublePredicate atLeast(double thresholdPercentage) {
return new scala.compat.java8.functionConverterImpls.FromJavaDoublePredicate(
actualPercentage -> actualPercentage >= thresholdPercentage);
}
FromJavaDoublePredicate f = atLeast(3.0);
Test.hasCompleteness(5, f); // true
PS. PS。 From what I saw, you chose scala-java8-compat , so I assumed you use an earlier version of Scala.
从我所见,您选择了scala-java8-compat ,所以我假设您使用的是 Scala 的早期版本。 Their maintainers state:
他们的维护者 state:
If you are using Scala 2.13 or newer only, then don't use this library!
如果您仅使用 Scala 2.13 或更新版本,请不要使用此库! Use the classes under
scala.jdk
instead;改用
scala.jdk
下的类; they were added to the standard library in 2.13.它们在 2.13 中被添加到标准库中。
So for Scala 2.13.x I recommend using the FromJavaDoublePredicate case class in the FunctionWrappers
object instead.因此,对于 Scala 2.13.x,我建议在
FunctionWrappers
object 中使用FromJavaDoublePredicate案例 class 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.