How does one implement the friend concept in Java (like C++)?
-
Even when I code in C++, I use `friend` extremely sparingly, if at all. Providing a public interface that can be used by all is much safer. – Code-Apprentice Jan 09 '13 at 00:06
-
I haven't used friend concept in Java in my code. I was just inquisitive for curiosity's sake. – FirstName LastName Jan 09 '13 at 00:07
-
@Code-Guru How would a public interface help? I might be missing something here. Can you post some link giving more details? – FirstName LastName Jan 09 '13 at 00:08
-
It might be useful to describe the problem you are actually solving, the one that you would have used friend for in C++. – Patricia Shanahan Jan 09 '13 at 00:08
-
@Code-Guru Almost every class I write, whether in C++ or Java, has a constructor which takes parameters and getXxx() methods to retrieve those values later. Occassionally, I will have setXxx() methods to allow a value to be changed, but those are rare because I don't like allowing the outside world to change the values of my private variables. With the getXxx() and setXxx() methods, I don't find any need to use friend. – Code-Apprentice Jan 09 '13 at 00:17
-
@Code-Guru With solely get and set methods, you cannot control which classes get access. You have to check the invoking class name to see that. I have added one more answer detailing the same. Let me know if anyone can figure out a better or simpler way. – FirstName LastName Jan 09 '13 at 02:01
-
1@AlastorMoody If you need that kind of control, your answer certainly solves the issue. As I stated in my comment above, I often don't even provide setter methods (i.e. my classes are almost all immutable). Read access is typically harmless as long as you take care with returning references to non-immutable classes (such as Collections). – Code-Apprentice Jan 09 '13 at 02:11
-
when should we use this types of implementation? did we really use this concept in real world java program? if not then what is the alternative of this concept? – Soumyadip Das Apr 12 '18 at 05:43
4 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.

- 23,465
- 21
- 80
- 106

- 1,891
- 5
- 23
- 37
-
1Very nice. A better way to implement this would perhaps be to declare class `B` as `final`, avoiding the potential security risks. – filpa Oct 09 '16 at 22:26
-
I think this is the same that: if you want to share a minimal part of api between A and B, just extract C. At least this is what you have done in practice. At that point, I will move the field to C as keeping it in A has no advantage (at least I don't see it). – Ignacio Baca Aug 04 '19 at 09:44
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.

- 44,725
- 9
- 65
- 93
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.

- 28,470
- 6
- 53
- 83
-
Indeed, however if there is already existing legacy code in place and refactoring is going to be a hassle and you don't want to change the visibility of fields and methods, then setting up such a friend fuctionality might be an option. I agree, it will not be highly readable or even recommended, but it works as a quick fix. – FirstName LastName Jan 09 '13 at 00:11
-
I feel the need to point out this a last ditch, out of options, worst case, welcome to sub-prime levels of technical debt, when it become permanently temporary, or temporarily permanent option. – Tony Hopkinson Jan 09 '13 at 00:15
-
Nearly all people that I know would just define the affected methods as public, but your approach is interesting – AlexWien Jan 09 '13 at 00:15
-
-
@TonyHopkinson it also depends if it will be a public API used by some people, or if that code will only be used by two people for the rest of the program life. – AlexWien Jan 09 '13 at 01:47
-
For Life? The only thing that doesn't change in IT, is things keep changing... – Tony Hopkinson Jan 09 '13 at 11:01
-
They can also be accessed by all classes in other packages that derive from that class. Package access and protected access are not the same in Java. Package level access is not regulated by the `protected` keyword. Actually, using `protected` broadens the package-private access level. – Florian Mar 03 '14 at 18:37
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);
}
}

- 1,891
- 5
- 23
- 37
-
I don't know, why this is done voted. For me it is a valid way. But I would throw an adequate exception instead of returning null. In addition I would use ' Thread.currentThread().getStackTrace()' instead of 'Throwable().getStackTrace()'. Further I would not write 'new String("example.java.testing.B")' but 'example.java.testing.B.class.getName()'. (can be found by reference search) – Maik Jan 03 '22 at 07:36
-
https://stackoverflow.com/questions/11306811/how-to-get-the-caller-class-in-java – Maik Jan 03 '22 at 07:48