【问题标题】:Java: How to limit access of a method to a specific class?Java:如何限制对特定类的方法访问?
【发布时间】:2012-07-18 20:06:17
【问题描述】:

这是一个例子:

class A 
{
   List l = new List ();
   list.insert("x");
}

class List
{
   ...
   public void insert ()
   {
      /*insertion occurs*/
   }
   ...
}

是否有可能将 insert() 方法保持为公共状态,但只限制对类 A 的访问,以便只有在从 A 调用时,其他类才能访问它?

【问题讨论】:

  • 您可以将List 设为A 中的内部类,因此其他类将无法访问它。其他方式可能是设置List#insert(A a)

标签: java class


【解决方案1】:

我会将调用该方法的对象作为参数传递,即

list.insert("x", this);

然后检查传入的Object是否是A类的实例

 public void insert (String x, Object o)
   {
      if(o instanceof ClassA){
         /*insertion occurs*/
      }
   }

【讨论】:

  • 这没有限制,每个人都可以将Object(或任何类)的实例传递给方法......
【解决方案2】:

如果方法是公开的,那么每个人都可以访问它。像您这样访问控制的技巧是通过接口公开一组公共操作,将辅助操作添加到实现该接口的私有类,并使您的用户编程到接口,而不是类。

这是一个例子:

public interface MyList {
    Object elementAt(int i);
}
public class A {
    private static class MyListImpl implements MyList {
        public Object elementAt(int i) {
            ...
        }
        public void insert(Object element) {
            ...
        }
    }
    private final MyListImpl list = new MyListImpl();
    public MyList getList() { return list; }
    public void insert(Object o) { list.insert(o); }
}

使用场景:

A a = new A();
a.insert(123);
a.insert("quick brown fox");
MyList lst = a.getList();
System.out.println(lst.elementAt(0));
System.out.println(lst.elementAt(1));

【讨论】:

    【解决方案3】:

    是的,您可以将调用对象作为参数传递,并在实际代码之前检查 insert() 方法。

      public void insert(Object obj){
        if(obj instanceof A){
          //your code block
        }
      }
    

    请注意,这将允许所有扩展 A 的类以及调用插入。如果您只想限制 A 类,请添加额外的检查。

      public void insert(Object obj){
        if((obj instanceof A) && obj.getClass().getSimpleName().equals("A")){
          //your code block
        }
      }
    

    我们也可以只使用条件“obj.getClass().getSimpleName().equals(“A”)”来实现第二种情况。

    【讨论】:

      【解决方案4】:

      使用访问修饰符最好的办法就是将方法包设为私有(删除public 关键字)并仅将这两个类保留在同一个包中。

      【讨论】:

        【解决方案5】:

        如果前面答案中的所有“内部类”内容都让您感到困惑,那么还有另一种可能更直观的方法(假设您已经了解了 extends 关键字和继承)。您可以简单地使insert() 方法protected 而不是public 并使class A 扩展List。例如:

        public class List {
           ...
           protected void insert() {
              //insertion occurs
           }
           ...
        }
        
        public class A extends List {
           ...
        }
        

        只要没有其他类扩展 List,就只有 AList 类型的对象才能使用 insert() 方法。

        【讨论】:

        • 或同一个包中的类。
        【解决方案6】:
        package problems;
        
        public class Problem1 {
            public static void main(String[] args) {
                B b = new B();
                b.methodInB();
                C c = new C();
                c.methodNotInB();
            }
        }
        
        class A {
            public void onlyB() {
                StackTraceElement[] stackTraceElements = Thread.currentThread()
                        .getStackTrace();
                if (!problems.B.class.getCanonicalName().equals(
                        stackTraceElements[stackTraceElements.length - 2]
                                .getClassName())) {
                    System.err.println("You are not authorized to call me!!");
                    return;
                }
                System.out.println("You are authorized to call me!!");
            }
        }
        
        class B {
            public void methodInB() {
                A a = new A();
                a.onlyB();
            }
        }
        
        class C {
            public void methodNotInB() {
                A a = new A();
                a.onlyB();
            }
        }
        

        【讨论】:

          【解决方案7】:

          把它作为内部类放在 A 中,或者你可以做另一件事...... 让 insert 接受一个类型为 Object 的参数,并在它的开头检查参数的类型是否为 A .... 当您调用它时发送调用对象... 也许这不是一个好主意,但它会做你想做的事

          【讨论】:

            【解决方案8】:

            将其放入允许的类并使其私有。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-02-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-07
              • 2011-05-09
              相关资源
              最近更新 更多