我将方法设置为public,因为它们必须由外部类调用,但我只希望通过一个或两个方法调用它们。被其他方法调用可能会在我的程序中产生错误。所以,为了防止我不小心围绕我自己的方法编程,我一直在我想限制调用者的方法中做这样的事情:
if(trace.length<2){
throw new Exception("Class should not call its own function.");
}else if(trace[1].getClassName()!=desiredClassName || trace[1].getMethodName()!=desiredMethodName){
throw new Exception(trace[1].getClassName()+"\" is invalid function caller. Should only be called by "+desiredClassName+"->"+desiredMethodName+".");
}
我还应该做些什么,或者我不应该忘记我的计划是如何运作的?
答案 0 :(得分:4)
您应该使用可见性来限制调用 - 将方法公开(或者就此而言,javadocing)不会起作用,除非您有dicipline(并且您也控制了调用者)。根据你的描述,你不是。
您可以做的是将类包设为私有,并将其放在与该类的两个调用者相同的包中。只要你有一个合适的包结构,这可以工作。例如。: 你的班级只能由A和B调用:
package thepackage.of.a.and.b;
//imports here
class CallableByAB {
public void methodA(){}
public void methodB(){}
}
A:
package thepackage.of.a.and.b;
public class A {
/*...other code here */
new CallableByAB().methodA();
/*...other code here */
}
B:
package thepackage.of.a.and.b;
public class B {
/*...other code here */
new CallableByAB().methodB();
/*...other code here */
}
其他类无法调用new CallableByAB()
或导入它。因此,安全。
答案 1 :(得分:3)
对于您不应该解决的问题,这似乎是一个非常脆弱的解决方案。
在这种特殊情况下,您在将来的维护中可能不会受到太大影响,只需要使用这些特殊防护装置的几种方法。但是想象一下,尝试将这种逻辑应用于大型代码库中的许多方法 - 这不是一个可行的事情。即使在你的情况下,你也是有效编写无法在其他环境中重复使用的代码。
你需要这样做的事实肯定反映了某种错误的设计。
我推断你有某种状态接口,如果意外调用它的状态会被搞砸。理想情况下,我希望使界面更健壮,但如果不能做到:如果有特定方法应该使用此接口,您可以将这些方法移动到特定类 - 也许是当前objtec的内部类 - 并且只有在这个类中可见的句柄?
private Class TheLegalCaller {
private RestrictedCallee myCallee = new RestricatedCallee() ; // or other creation
public void doOneThing() { myCallee.doOne(); }
public void doOtherThing() } myCallee.doOther(); }
}
现在的缺点是它只会将问题提升到一个水平,如果你在错误的地方随机使用TheLegalCaller,那么我猜你还有问题。但也许通过使限制非常明显,它有助于你的记忆?
答案 2 :(得分:0)
答案 3 :(得分:0)
我找到了一种非常简单的方法,但需要一些编码方法:
class AllowedCaller {
private Object key;
public boolean getKey(){
return key;
}
public void allowedCallingMethod(RestrictedAccessClass rac){
this.key = rac;
rac.restrictedMethod();
this.key = null;
}
}
class RestrictedAccessClass{
public void restrictedMethod(){
if(allowedCallerInstance.getKey() != this){
throw new NullPointerException("forbidden!");
}
// do restricted stuff
}
}
我认为可以改进以防止多线程同时访问restrictedMethod() 此外,密钥可以在AllowedCaller以外的其他类上(因此RestrictedAccessClass不需要知道AllowedClass),并且这种控制可以是集中的,因此它可以是一个ArrayList,而不是单个密钥,它允许在同时。