Java的Method.isVarArgs()不适用于scala中的方法

时间:2016-03-07 12:33:46

标签: scala

我是斯卡拉的新学习者。有问题我无法解决。我使用java反射来检查用scala编写的方法。(我在scala中找不到合适的方法) 像这样的代码:

case class SomeClass(udf: UDF) {
    // Get Method object of "eval" method in udf
    val evalMethod: Method = {
        var evalMethods: ListBuffer[Method] = new ListBuffer[Method]
        udf.getClass.getMethods.foreach(m => {
            if (m.getName().equals("eval")) {
                evalMethods += m
            }
        })
        if (evalMethods.length != 1) {
            throw new Exception(s"$udf must have only one eval method")
        }
        evalMethods(0)
    }

    val evalParamsType = {
        val hasVarArgs = evalMethod.isVarArgs // Not work here
        println("varargs:" + hasVarArgs) // Always false
        for (param <- evalMethod.getParameterTypes) {
            // do some thing
        }
        // return some thing
    }
}

trait UDF {
}

object SomeUDF extends UDF {
    def eval(fields: String*) = {
        // do something here
    }
}

代码可能看起来很奇怪,我必须使用反射来完成这项工作,因为&#34; eval&#34; UDF中的方法可以有不同的参数和返回类型。 (那是另一个问题......)

似乎java中的Method类无法识别scala中的varargs,有没有办法在java或scala中做这个工作?

1 个答案:

答案 0 :(得分:3)

Scala的varargs编码方案与java不同。

// used :javap SomeUDF in scala repl
public void eval(scala.collection.Seq<java.lang.String>);

Scala使用scala.collection.Seq。 Java使用Array。 您可以使用@scala.annotation.varargs告诉编译器生成java varargs桥接方法(将调用scala变体)。

object SomeUDF extends UDF {
    @scala.annotation.varargs
    def eval(fields: String*) = {
        // do something here
    }
}

scala repl javap输出现在包含一个java varargs方法。

public void eval(java.lang.String...)