Java - 通过调用方法来限制

时间:2011-01-22 05:55:41

标签: java

我将方法设置为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+".");
}

我还应该做些什么,或者我不应该忘记我的计划是如何运作的?

4 个答案:

答案 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,而不是单个密钥,它允许在同时。