Implementation of Friend concept in Java

<>

This question already has an answer here:

Answers


Java does not have the friend keyword from C++. There is, however, a way to emulate that; a way that actually gives a lot more precise control. Suppose that you have classes A and B. B needs access to some private method or field in A.

public class A {
    private int privateInt = 31415;

    public class SomePrivateMethods {
        public int getSomethingPrivate() { return privateInt;  }
        private SomePrivateMethods() { } // no public constructor
    }

    public void giveKeyTo(B other) {
        other.receiveKey(new SomePrivateMethods());
    }
}

public class B {
    private A.SomePrivateMethods key;

    public void receiveKey(A.SomePrivateMethods key) {
        this.key = key;
    }

    public void usageExample() {
        A anA = new A();

        // int foo = anA.privateInt; // doesn't work, not accessible

        anA.giveKeyTo(this);
        int fii = key.getSomethingPrivate();
        System.out.println(fii);
    }
}

The usageExample() shows how this works. The instance of B doesn't have access to the private fields or methods of an instance of A. But by calling the giveKeyTo(), class B can get access. No other class can get access to that method, since it a requires a valid B as an argument. The constructor is private.

The class B can then use any of the methods that are handed to it in the key. This, while clumsier to set up than the C++ friend keyword, is much more fine-grained. The class A can chose exactly which methods to expose to exactly which classes.

Now, in the above case A is granting access to all instances of B and instances of subclasses of B. If the latter is not desired, then the giveKeyTo() method can internally check the exact type of other with getClass(), and throw an exception if it is not precisely B.


Suppose A.foo() should only be called by B. This can be arranged by a token that can only be generated by B.

public class B
{
    public static class ToA { private ToA(){} }
    private static final ToA b2a = new ToA();

    void test()
    {
        new A().foo(b2a);
    }
}

public class A
{
    public void foo(B.ToA b2a)
    {
        if(b2a==null)
            throw new Error("you ain't B");
        // ...
    }
}

Only B can generate a non-null B.ToA token. If both A and B do not leak this token to the 3rd party, nobody else can invoke A.foo()

If A2 wants to friend B too, it needs a different token type. If it's the same token type, since A got a token of the type from B, A can pretend to be B to A2.

The check is done at runtime, not compile time, that is not perfect. Not a big deal though, since any 3rd party can only invoke A.foo() with a null, it can't be an innocent mistake which we want to check at compile time; it's probably malicious so we don't care to warn the caller at compile time.


In Java you can put both (or more) classes into the same package. All methods and fields with the protected qualifier can directly be accessed by all classes in that package.


I figured out another way to achieve the same. Basically you check the fully qualified name of the invoking class name. If it matches your "friend" function, then you give access, else you return null.

public class A {
    private static int privateInt = 31415;

    public static int getPrivateInt() { 
        if(Throwable().getStackTrace()[1].getClassName().equals(new String("example.java.testing.B")))
        {
        return privateInt; 
        }
        else
        {
        return null;
        }
    }
}


package example.java.testing;
public class B {

public void usageExample() {
    int foo = A.getPrivateInt; // works only for B
    System.out.println(foo);
    }
}

Need Your Help

ExecutorService, how to wait for all tasks to finish

java multithreading threadpool executorservice

What is the simplest way to to wait for all tasks of ExecutorService to finish? My task is primarily computational, so I just want to run a large number of jobs - one on each core. Right now my se...

Are any Javascript engines tail call optimized?

javascript functional-programming tail-recursion

I have a tail recursive pathfinding algorithm that I've implemented in Javascript and would like to know if any (all?) browsers would possibly get stack overflow exceptions.