从 Scala 重载调用 java varargs [英] calling java varargs from scala with overloading
问题描述
这是另一个关于与可变参数功能相关的 scala-java 兼容性的问题.关键区别在于java的部分是重载的.
It's another question about scala-java compatibility related to varargs feature. The key difference is that java's part is overloaded.
它类似于这个 Scala 代码:
It resembles this scala code:
object Test {
def test( xa : String* ) = print( xa.mkString(",") )
def test( xs : Seq[String] ) = print( xs.mkString(",") )
}
Scala 不同于 java 将这种重载标记为无效
Scala unlike java mark such overloading as invalid
error: double definition:
def test(xa: String*): Unit at line 11 and
def test(xs: Seq[String]): Unit at line 12
have same type after erasure: (xa: Seq)Unit
def test( xs : Seq[String] ) = print( xs.mkString(",") )
^
但是java同意编译类似的结构.
But java agrees to compile similar construction.
这让 scala 感到惊讶,它在尝试调用适当的 java 方法时产生错误.scala 编译器留下了此处不允许使用 `:_*' 注释(此类注释仅允许在 *-parameters 的参数中)"消息
That surprises scala and it produces an error trying to invoke appropriate java method. The scala compiler left "no `: _*' annotation allowed here (such annotations are only allowed in arguments to *-parameters)" message
这种情况下如何正确调用varargs方法?
How to properly invoke varargs method under such conditions?
我在 scala 问题跟踪器
I've found corresponding bug in the scala issues tracker
推荐答案
我在扩展一些 Java 接口时遇到了类似的问题.
I have run into a similar problem when extending some Java interfaces.
具体来说,org.hibernate.Session 有这两个虚方法:
Specifically, org.hibernate.Session has these two virtual methods:
ProcedureCall createStoredProcedureCall(String var1, Class... var2);
ProcedureCall createStoredProcedureCall(String var1, String... var2);
而且,正如您所经历的,如果您尝试直接在 Scala 类中实现它们,Scala 会出错.目前,我所知道的唯一解决方法是在 Java 中创建一个桥接"类来实现这两个方法并将它们的调用传递给两个没有重载命名的新虚函数.(见下例)
And, as you experienced, Scala gives an error if you try and implement them directly in a Scala class. At this time, the only work around that I know of is to create a "bridge" class in Java that implements the two methods and passes their calls to two new virtual functions that do not have overloaded naming. (see example below)
对于问题中给出的示例案例,由于不可能进行重载,因此有必要为这两个函数指定不同的名称.不幸的是,这是目前唯一可行的解决方案.
For the example case given in the question, since overloading will not be possible, it would be necessary to give the two functions distinct names. It is, unfortunately, the only solution that will work at this time.
@Override
public ProcedureCall createStoredProcedureCall(String procedureName, Class... resultClasses) {
return createStoredProcedureCall0(procedureName, resultClasses);
}
abstract ProcedureCall createStoredProcedureCall0(String procedureName, Class... resultClasses);
@Override
public ProcedureCall createStoredProcedureCall(String procedureName, String... resultSetMappings) {
return createStoredProcedureCall1(procedureName, resultSetMappings);
}
abstract public ProcedureCall createStoredProcedureCall1(String procedureName, String... resultSetMappings);
这篇关于从 Scala 重载调用 java varargs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!