我们可以使用反射来获取方法名称,如下所示:
object Foo { def bar(name:String, age:Int) = {} }
val foo = Foo.getClass
val methods = foo.getMethods.filter(_.getName.startsWith("b"))
methods.foreach(m => println(m.getName))
现在,我需要获取参数类型和名称。
String
和/或Array[String]
类型参数的函数感兴趣。[编辑:]解决方案的Java版本也可以。
[编辑:]注释似乎是做到这一点的一种方法。但是,Scala注释支持不是很好。相关的SO问题。
如果类中存在调试信息,则可以按照以下步骤进行操作。
我基本上是使用Adam Paynter的答案,并在稍作修改后从此处复制粘贴代码以使其在Scala中工作。
package test
import java.io.InputStream
import java.util.ArrayList
import scala.collection.JavaConversions._
import org.objectweb.asm.ClassReader
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.LocalVariableNode
import org.objectweb.asm.tree.MethodNode
object Util {
case class Param(paraName:String, paraType:Type)
case class ScalaMethod(name:String, returnType:Type, params:List[Param])
def main(args:Array[String]):Unit = {
getMethods(scala.util.Random.getClass).foreach(printMethod _ )
def printMethod(m:ScalaMethod) = {
println (m.name+" => "+m.returnType.getClassName)
m.params.foreach(p =>
println (" "+ p.paraName+":"+p.paraType.getClassName))
}
}
/**
* extracts the names, parameter names and parameter types of all methods of c
*/
def getMethods(c:Class[_]):List[ScalaMethod] = {
val cl:ClassLoader = c.getClassLoader();
val t:Type = Type.getType(c);
val url:String = t.getInternalName() + ".class";
val is:InputStream = cl.getResourceAsStream(url);
if (is == null)
throw new IllegalArgumentException("""The class loader cannot
find the bytecode that defined the
class (URL: " + url + ")""");
val cn = new ClassNode();
val cr = new ClassReader(is);
cr.accept(cn, 0);
is.close();
val methods = cn.methods.asInstanceOf[java.util.List[MethodNode]];
var mList:List[ScalaMethod] = Nil
if (methods.size > 0) for (i <- 1 to methods.size) {
val m:MethodNode = methods.get(i-1)
val argTypes:Array[Type] = Type.getArgumentTypes(m.desc);
val paraNames = new java.util.ArrayList[String](argTypes.length)
val vars = m.localVariables.asInstanceOf[java.util.List[LocalVariableNode]];
var pList:List[Param] = Nil
if (argTypes.length > 0) for (i <- 0 to argTypes.length) {
// The first local variable actually represents the "this" object
paraNames.add(vars.get(i).name);
pList = Param(paraNames.get(i-1), argTypes(i-1)) :: pList
}
mList = ScalaMethod(m.name, Type.getReturnType(m.desc), pList) :: mList
}
mList
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句