Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to simulate the C++ 'friend' concept in Java?

People also ask

Is there a friend function in Java?

friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of the class. Even though the prototypes for friend functions appear in the class definition, friends are not member functions.

Why is there no friend in Java?

It's simply wrong. While it's true that friend can be used to break encapsulation, so can other features be misused. Used correctly, friend enhances encapsulation because it enables a more fine-grained access control: friend replaces use of public , not use of private .

How do you define a Friends class in Java?

In object-oriented programming, a friend function, that is a "friend" of a given class, is a function that is given the same access as methods to private and protected data. A friend function is declared by the class that is granting access, so friend functions are part of the class interface, like methods.

Is friend a constructor?

The Friend constructor is not available as a constructor. Friend is function. which use to access the data and methods of the defined class. Because friend function is named as private in access the data in defined class.


Here is a small trick that I use in JAVA to replicate C++ friend mechanism.

Lets say I have a class Romeo and another class Juliet. They are in different packages (family) for hatred reasons.

Romeo wants to cuddle Juliet and Juliet wants to only let Romeo cuddle her.

In C++, Juliet would declare Romeo as a (lover) friend but there are no such things in java.

Here are the classes and the trick :

Ladies first :

package capulet;

import montague.Romeo;

public class Juliet {

    public static void cuddle(Romeo.Love love) {
        Objects.requireNonNull(love);
        System.out.println("O Romeo, Romeo, wherefore art thou Romeo?");
    }

}

So the method Juliet.cuddle is public but you need a Romeo.Love to call it. It uses this Romeo.Love as a "signature security" to ensure that only Romeo can call this method and checks that the love is real so that the runtime will throw a NullPointerException if it is null.

Now boys :

package montague;

import capulet.Juliet;

public class Romeo {
    public static final class Love { private Love() {} }
    private static final Love love = new Love();

    public static void cuddleJuliet() {
        Juliet.cuddle(love);
    }
}

The class Romeo.Love is public, but its constructor is private. Therefore anyone can see it, but only Romeo can construct it. I use a static reference so the Romeo.Love that is never used is only constructed once and does not impact optimization.

Therefore, Romeo can cuddle Juliet and only he can because only he can construct and access a Romeo.Love instance, which is required by Juliet to cuddle her (or else she'll slap you with a NullPointerException).


The designers of Java explicitly rejected the idea of friend as it works in C++. You put your "friends" in the same package. Private, protected, and packaged security is enforced as part of the language design.

James Gosling wanted Java to be C++ without the mistakes. I believe he felt that friend was a mistake because it violates OOP principles. Packages provide a reasonable way to organize components without being too purist about OOP.

NR pointed out that you could cheat using reflection, but even that only works if you aren't using the SecurityManager. If you turn on Java standard security, you won't be able to cheat with reflection unless you write security policy to specifically allow it.


The 'friend' concept is useful in Java, for example, to separate an API from its implementation. It is common for implementation classes to need access to API class internals but these should not be exposed to API clients. This can be achieved using the 'Friend Accessor' pattern as detailed below:

The class exposed through the API:

package api;

public final class Exposed {
    static {
        // Declare classes in the implementation package as 'friends'
        Accessor.setInstance(new AccessorImpl());
    }

    // Only accessible by 'friend' classes.
    Exposed() {

    }

    // Only accessible by 'friend' classes.
    void sayHello() {
        System.out.println("Hello");
    }

    static final class AccessorImpl extends Accessor {
        protected Exposed createExposed() {
            return new Exposed();
        }

        protected void sayHello(Exposed exposed) {
            exposed.sayHello();
        }
    }
}

The class providing the 'friend' functionality:

package impl;

public abstract class Accessor {

    private static Accessor instance;

    static Accessor getInstance() {
        Accessor a = instance;
        if (a != null) {
            return a;
        }

        return createInstance();
    }

    private static Accessor createInstance() {
        try {
            Class.forName(Exposed.class.getName(), true, 
                Exposed.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e);
        }

        return instance;
    }

    public static void setInstance(Accessor accessor) {
        if (instance != null) {
            throw new IllegalStateException(
                "Accessor instance already set");
        }

        instance = accessor;
    }

    protected abstract Exposed createExposed();

    protected abstract void sayHello(Exposed exposed);
}

Example access from a class in the 'friend' implementation package:

package impl;

public final class FriendlyAccessExample {
    public static void main(String[] args) {
        Accessor accessor = Accessor.getInstance();
        Exposed exposed = accessor.createExposed();
        accessor.sayHello(exposed);
    }
}

There are two solutions to your question that don't involve keeping all classes in the same package.

The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).

The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.

Related Questions: 1, 2, and 3.


As far as I know, it is not possible.

Maybe, You could give us some more details about Your design. Questions like these are likely the result of design flaws.

Just consider

  • Why are those classes in different packages, if they are so closely related?
  • Has A to access private members of B or should the operation be moved to class B and triggered by A?
  • Is this really calling or is event-handling better?

eirikma's answer is easy and excellent. I might add one more thing: instead of having a publicly accessible method, getFriend() to get a friend which cannot be used, you could go one step further and disallow getting the friend without a token: getFriend(Service.FriendToken). This FriendToken would be an inner public class with a private constructor, so that only Service could instantiate one.