【问题标题】:Getting a Method Object without Addressing the Method by Name在不通过名称寻址方法的情况下获取方法对象
【发布时间】:2012-03-26 07:53:49
【问题描述】:

有没有办法不使用方法名来获取方法对象?

例如我有课:

class Car {

    public String drive();
    public String giveUp();
    public String fillUp();
}

我想创建一个Map<String, Method> 方法(又名:("move", drive()), ("name", giveUp()), ....)。

由于使用了混淆,我无法通过名称获取方法对象。有没有办法在不绑定 this 的情况下获取方法名称?

我想另一种方法是:

对于拥有 getClass() 的类,是否有等价的方法?我正在寻找类似于 giveUp.Method 的东西。

【问题讨论】:

  • 尽管我很欣赏拼写错误“混淆”的讽刺意味,但请尽量小心不要生成拼写错误的标签,尤其是当您有自动完成功能时。
  • 嘿,我把自动完成归咎于那个。
  • 嘿为什么不除了混淆的方法?即,您要么按名称访问方法,要么混淆,您的两个目标没有结合,并且通过解决方法假装它们是徒劳的。在最坏的情况下,创建一个 if(key) { // key 的调用方法 } else if(nextKey) {...}.

标签: java reflection obfuscation


【解决方案1】:

Java 中没有 Car.giveUp.method() 这样的构造,因为方法不像类和对象那样是“一等公民”。

在不知道混淆器对您的代码做了什么或添加额外信息的情况下,您无法区分这些方法,因为除了它们的名称之外,它们具有相同的签名。

  • 一些混淆器会生成将原始名称映射到经过混淆的名称的文本文件,您可以使用该映射文件在运行时识别经过混淆的方法。

  • 你可以给方法加注解,比如

    @MappedMethod("move")
    public String drive();
    

    带有自写注释@MappedMethodString 类型的默认属性。然后使用反射获取所有方法及其注解,并将注解值作为key。

【讨论】:

    【解决方案2】:

    你可以使用反射来获取所有的方法。

    Class<Car> clazz = Car.class;
    Method[] methods = clazz.getDeclaredMethods();
    

    你迭代方法并映射它们:

    for(Method method: methods)
        map.put( method.getName(), method);
    

    【讨论】:

    • 我有一个特定的方法名称,我不需要映射所有的方法。目标是拥有 map.get("name").invoke(...)。由于混淆器,方法名称无论如何都会改变。
    猜你喜欢
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多