我们如何才能将任何受保护方法的访问限制为仅对任何包中的子类而不是对同一包中的类的访问。
如果任何不是子类并且在同一个包中的类也必须抛出像“受保护的方法”这样的异常。
编辑:有什么方法可以检查调用类名实例,然后我们可以使用instanceof进行验证。
我们如何才能将任何受保护方法的访问限制为仅对任何包中的子类而不是对同一包中的类的访问。
如果任何不是子类并且在同一个包中的类也必须抛出像“受保护的方法”这样的异常。
编辑:有什么方法可以检查调用类名实例,然后我们可以使用instanceof进行验证。
这不可能。您可以在protected
修饰符(同一个包中的子类 + 类)和默认修饰符(同一个包中的类)之间进行选择。没有第三种选择。
此外,您无法在运行时轻松执行此操作,因为找到调用代码的类名和包并不容易。请参阅:如何使用堆栈跟踪或反射找到方法的调用者?
一种选择是使用aspectj。它甚至可以在编译时拒绝尝试访问protected
同一包中的方法而不是子类的代码(借助declare warning
anddeclare error
指令)。您可能希望包含一些编译时注释,例如@SubclassesOnly
. 请参阅:重新审视编译时架构实施:AspectJ、Maven 和 Eclipse以及使用 AspectJ 进行编译时检查。
简单:从包中删除所有其他类,只留下你的基类。
这将意味着唯一可以访问您的类的类来自另一个包。
如果另一个库复制了您的包名称,您可以轻松检查调用者的包并断言它与您的不同:
if (getClass().getPackage().equals(MyBaseClass.class.getPackage())
throw new IllegalAccessError(); // or similar
仅供参考getClass()
,为您提供 的类this
,这将是子类的类。
要查找调用者的类,请使用以下代码:
Class<?> callerClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());