我们如何将任何受保护方法的访问权限仅限于任何包中的子类而不是同一包中的类。
如果任何不是子类且在同一个包中的类也必须抛出异常,例如“受保护的方法”。
编辑:有没有办法检查调用类名实例,然后我们可以使用 instanceof 进行验证。
答案 0 :(得分:7)
这是不可能的。您可以在protected
修饰符(同一包中的子类+类)和默认修饰符(同一包中的类)之间进行选择。没有第三种选择。
此外,您无法在运行时轻松强制执行该操作,因为查找调用代码的类名和包并不简单。请参阅:How do I find the caller of a method using stacktrace or reflection?
一种选择是使用aspectj。它甚至可以在编译时工作,拒绝尝试从同一个包中访问protected
方法而不是子类的代码(在declare warning
和declare error
指令的帮助下)。您可能希望包含一些编译时注释,如@SubclassesOnly
。请参阅:Compile-time architecture enforcement revisited: AspectJ, Maven and Eclipse和Compile-time checks with AspectJ。
答案 1 :(得分:3)
简单:从包中删除所有其他类,只留下您的基类。
这意味着可以访问您班级的唯一课程来自另一个包。
如果另一个库复制了您的包名,您可以轻松检查调用者的包并断言它与您的包不同:
if (getClass().getPackage().equals(MyBaseClass.class.getPackage())
throw new IllegalAccessError(); // or similar
FYI getClass()
为您提供了this
的类,它将是子类的类。
要查找调用者的类,请使用以下代码:
Class<?> callerClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());