【问题标题】:Better to use reflection or my little hack to access a private method?更好地使用反射或我的小技巧来访问私有方法?
【发布时间】:2013-08-28 19:12:26
【问题描述】:

我需要从另一个类访问私有方法。我有两种访问方式。首先是明显的反映。第二个是一种黑客攻击。我需要调用的私有方法是从受保护的内部类的 accessPrivateMethod 方法调用的。这个方法实际上只会调用我需要的私有方法。那么,是使用反射来访问它更好,还是通过扩展调用它的受保护内部类来更好地“破解”它。见代码:

method = object.getClass().getDeclaredMethod("privateMethod");
method.setAccessible(true);
Object r = method.invoke(object);

或者: (ProtectedInnerClass 是我要访问其私有方法的类中的受保护内部类。)

class Hack extends ProtectedInnerClass {
    public void accessPrivateMethod() {
        // callPrivateMethod literally only calls the private method
        // I need to call.
        super.callPrivateMethod();
    }
}
...
Hack.accessPrivateMethod();

一些额外的想法:

1) 我在这里看到很多人说仅将反射用作最后的手段。

2) 反射会导致安全问题吗? (SecurityManager 有时可以拒绝 setAccessible?)这需要在任何机器/设置上一直有效。

如果我的 hack 不清楚,请说出来,我会尝试详细说明。谢谢!

PS:我需要访问的私有方法在 JUNG 库中。调用它修复了一个错误。 AKA 我正在尝试找到一种解决方法,而无需编辑任何 JUNG jar。

【问题讨论】:

  • 这是糟糕设计的标志。
  • 如果你需要使用另一个类的private方法,那么它必须不是private,而是protectedpublic。假设此方法来自第三方库,您无法更改代码您可以访问代码,我建议将此代码移动到实用程序类并从那里使用它。跨度>
  • 如果该方法在另一个类中是私有的,则您不应该访问它。如果必须这样做,那你的设计就很糟糕。
  • 顺便说一句,你不能从子类访问任何private 字段或方法,甚至不能使用super 关键字,所以你的 hack 不起作用.
  • 我需要访问的私有方法在 JUNG 库中。调用它修复了一个错误。 AKA 我正在尝试找到一种解决方法,而无需编辑任何 JUNG jar。

标签: java inheritance reflection


【解决方案1】:

1) 我在这里看到很多人都说只能将反射作为最后的手段。

假设您的 hack 确实有效,最好使用它,而不是使用反射。这是因为使用反射的成本要高得多。

这是Java's API concerning reflection的摘录:

  • 由于反射涉及动态解析的类型,某些 Java 虚拟机优化无法执行。因此,反射操作的性能比它们的非反射操作慢,应该避免在对性能敏感的应用程序中频繁调用的代码段中。

2) 反射会导致安全问题吗? (SecurityManager 有时可以拒绝 setAccessible?)这需要在任何机器/设置上一直有效。

同样:

  • 反射需要运行时权限,在安全管理器下运行时可能不存在该权限。对于必须在受限安全上下文(例如 Applet)中运行的代码,这是一个重要的考虑因素。

因此,不仅 setAccessible 方法可能会被拒绝,整个反射使用也会被拒绝。

另一个考虑是,为了在不实例化的情况下调用您的 Hack 类方法,您需要将内部方法设置为静态。

class Hack extends ProtectedInnerClass {
   public static void accessPrivateMethod() {
       super.callPrivateMethod();
   }
}
Hack.accessPrivateMethod();

【讨论】:

    【解决方案2】:

    这个问题的出现可能是由于糟糕的设计或 Java 不允许“子包”可见性造成的。但是,如果性能是一个问题,请选择“小”黑客。否则,请选择使用反射的美学解决方案。但首先,请尝试确定您的设计是否良好。

    【讨论】:

    • 子包可见性是什么意思?
    • 我添加了 PS 说明,解释了我这样做的原因。我永远不会使用这种策略来设计一些东西:“我需要访问的私有方法在 JUNG 库中。调用它可以修复错误。AKA 我正在尝试找到一种解决方法,而无需编辑任何 JUNG jar”
    • com.mycompanycom.mycompany.gui 是完全不同的包,但是,它们可能看起来很熟悉。当使用protected 可见性时,这些包不能使用彼此的受保护方法。即使是com.mycompany.gui 包也不能使用来自com.mycompany 的受保护内容。
    • 是的,但只能通过类继承。
    猜你喜欢
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 2015-10-14
    相关资源
    最近更新 更多