如何限制受保护的方法只能访问子类

我们如何将任何受保护方法的访问限制为仅在任何包中的子类而不是同一包中的类。

如果任何不是子类且在同一个包中的类也必须抛出exception,例如“受保护的方法”。

编辑:有没有办法检查调用类名实例,然后我们可以使用instanceof进行validation。

简单:从包中删除所有其他类,只留下您的基类。

这意味着可以访问您的类的唯一类来自另一个包。

如果另一个库复制了您的包名,您可以轻松检查调用者的包并断言它与您的包不同:

if (getClass().getPackage().equals(MyBaseClass.class.getPackage()) throw new IllegalAccessError(); // or similar 

FYI getClass()为您提供了这个类,它是子类的类。

编辑:

要查找调用者的类,请使用以下代码:

 Class callerClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName()); 

这不可能。 您可以在protected modifier(同一包中的子类+类)和默认修饰符(同一包中的类)之间进行选择。 没有第三种选择。

此外,您无法在运行时轻松强制执行该操作,因为查找调用代码的类名和包并不简单。 请参阅: 如何使用堆栈跟踪或reflection查找方法的调用方?

一种选择是使用aspectj 。 它甚至可以在编译时工作,拒绝尝试从同一个包访问protected方法而不是子类的代码(在declare warningdeclare error指令的帮助下)。 您可能希望包含一些编译时注释,如@SubclassesOnly 。 请参阅: 重新编写编译时体系结构实施:AspectJ,Maven和Eclipse以及使用AspectJ进行编译时检查 。