简体   繁体   English

通过重载从Scala调用Java varargs

[英]calling java varargs from scala with overloading

It's another question about scala-java compatibility related to varargs feature. 这是关于与varargs功能相关的scala-java兼容性的另一个问题。 The key difference is that java's part is overloaded. 关键区别在于java的部分已过载。

It resembles this scala code: 它类似于以下scala代码:

object Test {
  def test( xa : String* ) = print( xa.mkString(",") )
  def test( xs : Seq[String] ) = print( xs.mkString(",") )
}

Scala unlike java mark such overloading as invalid Scala不像Java将此类重载标记为无效

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(",") )
             ^

But java agrees to compile similar construction. 但是java同意编译类似的构造。

That surprises scala and it produces an error trying to invoke appropriate java method. 这让scala感到惊讶,并在尝试调用适当的java方法时产生错误。 The scala compiler left "no `: _*' annotation allowed here (such annotations are only allowed in arguments to *-parameters)" message scala编译器留下“此处不允许使用no:__'注释(这样的注释仅在* -parameters的参数中允许)”消息

How to properly invoke varargs method under such conditions? 在这种情况下如何正确调用varargs方法?


I've found corresponding bug in the scala issues tracker 我在scala问题跟踪器中找到了相应的错误

I have run into a similar problem when extending some Java interfaces. 扩展某些Java接口时,我遇到了类似的问题。

Specifically, org.hibernate.Session has these two virtual methods: 具体来说,org.hibernate.Session具有以下两个虚拟方法:

ProcedureCall createStoredProcedureCall(String var1, Class... var2);

ProcedureCall createStoredProcedureCall(String var1, String... var2);

And, as you experienced, Scala gives an error if you try and implement them directly in a Scala class. 而且,正如您所经历的那样,如果尝试直接在Scala类中实现它们,Scala会给出错误。 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. 目前,我所知的唯一解决方法是在Java中创建一个“桥”类,该类实现这两种方法,并将它们的调用传递给两个没有重命名的新虚拟函数。 (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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM