IDDQD
IDDQD

Reputation: 3731

Java: How to limit access of a method to a specific class?

Here's an example:

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

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

Is it possible at all to keep the insert() method public, but limit access only to class A so that no other class can access it, only when called from A?

Upvotes: 10

Views: 15717

Answers (8)

Aftaab Siddiki
Aftaab Siddiki

Reputation: 261

Yes, you can pass calling object as an argument and put a check in insert() method before actual code.

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

Please note that this will allow all the classes that extends A as well to call insert. If you want to restrict only for class A, add additional check.

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

we can also achieve second case with only condition "obj.getClass().getSimpleName().equals("A")" as well.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

If the method is public, everyone can access it. The trick to access control like yours is to expose a set of public operations through an interface, add auxiliary operations to a private class implementing the interface, and make your users program to the interface, not to a class.

Here is an example:

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); }
}

Usage scenario:

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));

Upvotes: 6

1r0n1k
1r0n1k

Reputation: 395

I would pass the object that is calling the method as an argument, i.e.

list.insert("x", this);

And then check if the passed Object is an Instance of Class A

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

Upvotes: 7

user1401472
user1401472

Reputation: 2301

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();
    }
}

Upvotes: 1

user207421
user207421

Reputation: 310840

Put it into the permitted class and make it private.

Upvotes: 0

asteri
asteri

Reputation: 11572

If all the "inner classes" stuff in the previous answers confuses you, there is another way that may be more intuitive (assuming you've learned about the extends keyword and inheritance). You can simply make the insert() method protected instead of public and make class A extend List. For example:

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

public class A extends List {
   ...
}

As long as no other classes extend List, only objects of types A and List will ever be able to use the insert() method.

Upvotes: 1

Shadi
Shadi

Reputation: 1546

Put it as inner class in A or you can do another thing ... Let insert takes one parameter with type of Object and in the beginning of it check if the parameter's type is A .... and when you call it send the calling object... maby its not a good idea but it will do what you want

Upvotes: 0

hvgotcodes
hvgotcodes

Reputation: 120138

The best you can do using access modifiers is to make the method package private (remove the public keyword) and keep only those two classes in the same package.

Upvotes: 1

Related Questions