3

我正在解析一个返回 Java 方法签名的报告,如下所示:

method(Ljava/lang/String;[Ljava/lang/String;ZI)V

将其转换回更易于阅读的内容的最佳方法是什么?例如,上面应该是这样的:

void method(String, String, boolean, int)
4

3 回答 3

3

以下是执行此操作的几个代码示例:

如果一切都失败了,您可以从这些地方的一个或其他地方复制代码。

有几点需要注意:

  • 您无法为签名恢复有意义的变量名称(显然......)
  • 如果方法是通用的,则不会在签名中指明。签名信息用于原始(已擦除)方法类型。
于 2012-09-08T02:56:51.433 回答
1

如果一个人想要实现他们自己的(就像我将在 Scala 中做的那样,如果只是为了练习一下它的解析功能),来自http://asm.ow2.org/doc/faq.html#Q7描述了 mangling:

  • 原始表示:
    • 'V' - 无效
    • 'Z' - 布尔值
    • 'C' - 字符
    • 'B' - 字节
    • 'S' - 短
    • '我' - 整数
    • 'F' - 浮动
    • 'J' - 长
    • 'D' - 双倍
  • 类表示:
    • L
    • Ljava/io/ObjectOutput;
    • Ljava/语言/字符串;

它唯一缺少的是似乎以'['(例如[Z)为前缀的数组,可能每个维度一个。

于 2012-09-09T15:15:11.590 回答
1

在斯卡拉:

import scala.util.parsing.combinator.RegexParsers

class JavaSignatureParser extends RegexParsers {
  def signature: Parser[String] = methodName ~ "(" ~ parameters ~ ")" ~ result ^^ {
    case m ~ "(" ~ p ~ ")" ~ r => r + " " + m + "(" + p + ")"
  }
  def methodName: Parser[String] = regularName ~ opt(specialName) ^^ {
    case m ~ None => m
    case c ~ Some(s) => c + s
  }
  def regularName: Parser[String] = """[A-Z0-9a-z_.$]+""".r
  def specialName: Parser[String] = "&lt;" ~> initializer <~ "&gt;" ^^ ("<" + _ + ">")
  def initializer: Parser[String] = "init" | "clinit"
  def result: Parser[String] = void | nonVoid
  def parameters: Parser[String] = rep(nonVoid) ^^ {
    case Nil => ""
    case p => p.reduceLeft(_ + ", " + _)
  }
  def nonVoid: Parser[String] = primitive | reference | array
  def primitive: Parser[String] = boolean | char | byte | short | int | float | long | double
  def void: Parser[String] = "V" ^^ (_ => "void")
  def boolean: Parser[String] = "Z" ^^ (_ => "boolean")
  def char: Parser[String] = "C" ^^ (_ => "char")
  def byte: Parser[String] = "B" ^^ (_ => "byte")
  def short: Parser[String] = "S" ^^ (_ => "short")
  def int: Parser[String] = "I" ^^ (_ => "int")
  def float: Parser[String] = "F" ^^ (_ => "float")
  def long: Parser[String] = "J" ^^ (_ => "long")
  def double: Parser[String] = "D" ^^ (_ => "double")
  def reference: Parser[String] = "L" ~> """[^;]+""".r <~ ";" ^^ { path =>
    val JavaName = """^java\..*\.([^.]+)""".r
    val fqcn = (path.replaceAll("/", "."))

    fqcn match {
      case JavaName(simpleName) => simpleName
      case qualifiedName => qualifiedName
    }
  }
  def array: Parser[String] = "[" ~> nonVoid ^^ (_ + "[]")
}
于 2012-09-11T18:00:30.447 回答