如何防止从特定类调用公共方法

2022-09-02 09:56:36

我有一个想要向其中添加方法的现有类。但我希望该方法只能从特定类中的特定方法调用。有没有办法阻止来自其他类/方法的调用?

例如,我有一个现有的类 A

public final class A
{
    //other stuff available for all classes/methods

    //I want to add a method that does its job only if called from a specific method of a class, for example:

    public void method()
    {
        //proceed if called from Class B.anotherMethod() else throw Exception
    }
}

执行此操作的一种方法是获取内部,然后确认父方法?StackTracemethod()

我正在寻找的是一种更干净,更可取的解决方案,例如模式之类的解决方案。


答案 1

说实话,你已经把自己画到了一个角落里。

如果类 A 和 B 不相关,也不是同一包的成员,则可见性无法解决问题。(即使确实如此,反射也可以用来颠覆可见性规则。

如果代码可以使用反射来调用该方法,则静态代码分析无法解决问题。

将 和 检查作为额外的参数传递给 没有帮助,因为其他类可以传递实例。B.thisA.method(...)CB

这只剩下堆栈跟踪方法1...或者放弃并依靠程序员2的良好意识来不调用他们不应该调用的方法。


理想的解决方案是重新审视让你陷入这种混乱的设计和/或编码决策。


1 - 有关使用注释,安全管理器等向应用程序员隐藏堆栈跟踪内容的示例,请参阅其他答案。但请注意,在引擎盖下,每个方法调用的开销可能要增加数百,甚至数千条指令。

2 - 不要低估程序员的良好意识。大多数程序员,当他们看到不调用某种方法的建议时,很可能会遵循该建议。


答案 2

正确的方法是安全管理器。

定义所有要调用的代码都必须具有的权限,然后确保仅具有该权限(这也意味着没有类具有 )。A.method()BAAllPermission

在 中,您可以使用 检查这一点,并在 中调用 中的方法。ASystem.getSecurityManager().checkPermission(new BMethodPermission())BAccessController.doPrivileged(...)

当然,这需要安装安全管理器(并且它使用合适的策略) - 如果不是,则所有代码都是受信任的,每个人都可以调用所有内容(如有必要,使用Reflectr)。