I have a Java class that has some private variable that I don't intend to create setters and getters for; I want these variables to remain inaccessible. But there is one class that needs access to these variables. This class is a visitor in a different package (and I'd prefer to keep it in a different package). Is it bad practice to allow this class to provide the visitor with Consumers and Suppliers, that act as setters and getters, so that the visitor could read and modify these variables? If yes, please state the reasons.
Example:
A.java
public class A {
private int x;
private Consumer<Integer> setter;
private Supplier<Integer> getter;
public A(int v) {
x = v;
setter = new Consumer<Integer>() {
#Override
public void accept(Integer t) {
x = t;
}
};
getter = new Supplier<Integer>() {
#Override
public Integer get() {
return x;
}
};
}
public void accept(SomeVisitor visitor) {
visitor.setSetter(setter);
visitor.setGetter(getter);
visitor.visit(this);
}
}
SomeVisitor.java
public class SomeVisitor extends ParentVisitor {
private Consumer<Integer> setter;
private Supplier<Integer> getter;
public SomeVisitor() {
setter = null;
getter = null;
}
public void setSetter(Consumer<Integer> setter) {
this.setter = setter;
}
public void setGetter(Supplier<Integer> getter) {
this.getter = getter;
}
#Override
public void visit(A a) {
// Code that will, possibly, read and modify A.x
...
}
}
This way the variable A.x remains inaccessible to every class except the visitor.
More Details:
I have some classes that will make use of the visitors. These classes have private variables that are dependent on one another. If these variables had setters, inconsistencies could arise as users change these variables, that should be dependent on one another, without respecting these dependecies.
Some of these variables will have getters, others won't as they will only be used internally and shouldn't be accessed elsewhere. The reason the visitors are an exception and should get read/write access to these variables is that the functionality the visitors are intended to implement were meant to be implemented within methods in these classes. But I thought it will be cleaner if I used visitors. And these functionalities do need read/write access to these variables.
The intention behind this approach was to emulate the friend feature in C++. I could place the visitors within the same package as these classes (which I would do if I didn't find a neat solution to this problem); But I think the package will look messy if it had the visitors as well (and there will be many visitors).
The functionality the visitors will implement will also have something to do with these classes relations to one another.
I tried to squeeze it into a comment, as it technically does not answer the question about whether this is a "Bad Practiceâ„¢", but this term is hard to define, and thus, it is nearly impossible to give an answer anyhow...
This eventually seems to boil down to the question of how to Make java methods visible to only specific classes (and there are similar questions). The getter/setter should only be available to one particular class - namely, to the visitor.
You used very generic names and descriptions in the question, and it's hard to say whether this makes sense in general.
But some points to consider:
One could argue that this defeats the encapsulation in general. Everybody could write such a visitor and obtain access to the get/set methods. And even though this would be a ridiculous hack: If people want to achieve a goal, they will do things like that! (sketeched in Appendix 1 below)
More generally, one could argue: Why is only the visitor allowed to access the setter/getter, and other classes are not?
One convincing reason to hide getter/setter methods behind Supplier/Consumer instances could be related to visibility and the specificness of classes (elaborated in Appendix 2). But since the visitor always has the dependency to the visited class, this is not directly applicable here.
One could argue that the approach is more error prone. Imagine the case that either the setter or the getter are null, or that they belong to different instances. Debugging this could be awfully hard.
As seen in the comments and other answer: One could argue that the proposed approach only complicates things, and "hides" the fact that these are actually setter/getter methods. I wouldn't go so far to say that having setter/getter methods in general already is a problem. But your approach is now to have setter-setters and getter-setters in a visitor. This extends the state space of the visitor in a way that is hard to wrap the head around.
To summarize:
Despite the arguments mentioned above, I would not call it a "bad practice" - also because it is not a common practice at all, but a very specific solution approach. There may be reasons and arguments to do this, but as long as you don't provide more details, it's hard to say whether this is true in your particular case, or whether there are more elegant solutions.
Update
For the added details: You said that
inconsistencies could arise as users change these variables
It is usually the responsibility of a class to manage its own state space in a way that makes sure that it is always "consistent". And, in some sense, this is the main purpose of having classes and encapsulation in the first place. One of the reasons of why getters+setters are sometimes considered as "evil" is not only the mutability (that should usually be minimized). But also because people tend to expose properties of a class with getters+setters, without thinking about a proper abstraction.
So specifically: If you have two variables x and y that depend on one another, then the class should simply not have methods
public void setX(int x) { ... }
public void setY(int y) { ... }
Instead, there should (at best, and roughly) be one method like
public void setState(int x, int y) {
if (inconsistent(x,y)) throw new IllegalArgumentException("...");
...
}
that makes sure that the state is always consistent.
I don't think that there is a way of cleanly emulating a C++ friend function. The Consumer/Supplier approach that you suggested may be reasonable as a workaround. Some (not all) of the problems that it may cause could be avoided with a slightly different approach:
The package org.example contains your main class
class A {
private int v;
private int w;
public void accept(SomeVisitor visitor) {
// See below...
}
}
And the package org.example also contains an interface. This interface exposes the internal state of A with getter+setter methods:
public interface InnerA {
void setV(int v);
int getV();
void setW(int w);
int getW();
}
But note that the main class does not implement this interface!
Now, the visitors could reside in a different packakge, like org.example.visitors. And the visitor could have a dedicated method for visiting the InnerA object:
public class SomeVisitor extends ParentVisitor {
#Override
public void visit(A a) {
...
}
#Override
public void visit(InnerA a) {
// Code that will, possibly, read and modify A.x
...
}
The implementation of the accept method in A could then do the following:
public void accept(SomeVisitor visitor) {
visitor.accept(this);
visitor.accept(new InnerA() {
#Override
public void setX(int theX) {
x = theX;
}
#Override
public int getX() {
return x;
}
// Same for y....
});
}
So the class would dedicatedly pass a newly created InnerA instance to the visitor. This InnerA would only exist for the time of visiting, and would only be used for modifying the specific instance that created it.
An in-between solution could be to not define this interface, but introduce methods like
#Override
public void visit(Consumer<Integer> setter, Supplier<Integer> getter) {
...
}
or
#Override
public void visit(A a, Consumer<Integer> setter, Supplier<Integer> getter) {
...
}
One would have to analyze this further depending on the real application case.
But again: None of these approaches will circumvent the general problem that when you provide access to someone outside of your package, then you will provide access to everyone outside of your package....
Appendix 1: A class that is an A, but with public getter/setter methods. Goodbye, encapsulation:
class AccessibleA extends A {
private Consumer<Integer> setter;
...
AccessibleA() {
EvilVisitor e = new EvilVisitor();
e.accept(this);
}
void setSetter(Consumer<Integer> setter) { this.setter = setter; }
...
// Here's our public setter now:
void setValue(int i) { setter.accept(i); }
}
class EvilVisitor {
private AccessibleA accessibleA;
...
public void setSetter(Consumer<Integer> setter) {
accessibleA.setSetter(setter);
}
...
}
Appendix 2:
Imagine you had a class like this
class Manipulator {
private A a;
Manipulator(A a) {
this.a = a;
}
void manipulate() {
int value = a.getValue();
a.setValue(value + 42);
}
}
And now imagine that you wanted to remove the compile-time dependency of this class to the class A. Then you could change it to not accept an instance of A in the constructor, but a Supplier/Consumer pair instead. But for a visitor, this does not make sense.
As getters and setters are evil anyway, you'll be better off making things not more complicated than ordinary getters and setters.
I am writing a utility which uses some classes defined in a 3rd party library which i do not control.
I would like the to know what would be a good way to handle situations like the one described below :
3rd party library has a base abstract class 'Food' which is extended by 'Appetizer','Entree',"Beverage' and 'Dessert'. (all part of 3rd Party Library)
I am writing a 'WaiterUtility' which has methods to serve each type of food.
I want to avoid an endless chain of instanceof checks .
`
Class WaiterUtility{
public serveItems(Food[] items)
{
for(Food aFood : items){
//how do i call the sub-class specific methods i wrote below?
}
}
private void serve(Appetizer aFood){//somecode}
private void serve(Entree aFood){//somecode}
private void serve(Beverage aFood){//somecode}
private void serve(Dessert aFood){//somecode}
}
`
If at all possible, I would implore you NOT to use reflection as TBotV63 does in his answer (he even says to avoid it). From the Oracle documentation:
If it is possible to perform an operation without using reflection, then it is preferable to avoid using it.
So, obviously we're inclined to say that all Foods can be served, and that any Waiter can serve any kind of Food. Ideally a good API would therefore expose methods that would be sufficient for a serve(Food) method to do the job without knowledge of what kind of food it is. It seems like your question implies that this is not the case, and therefore something more needs to be done.
If the 3rd party library accepts community input then you should try to open an issue or a pull request to add the functionality.
Obviously that's not always possible, so the next best thing to do would be to create an interface (something like Serveable) which defines the methods you would need, and then subclass the different types of food while implementing that interface. Then you would have Waiter.serve(Serveable).
This is more work than reflection or many uses of instanceof, but it is better OO design.
Why reflection is bad
The documentation for reflection points out 3 drawbacks of reflection
exposure of internals
performance
security
While you might not care about 2 or 3, 1 is especially bad.
... use of reflection can ... render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.
Why instanceof is bad (in this case)
serveItems(Food[]) implies to the caller that if you pass it several Food items, it will serve each of them. However this is not really the case. We can only serve certain sub-classes of Food, and we will have run-time errors if we try anything else. Java is a nice typesafe language, we like compile-time errors much more than run-time errors.
Another downside is that additional code needs to be added to Waiter every time a new sub-class of Food is added or changed. This becomes a cross-cutting concern and makes the code unscalable from a development perspective.
These are by no means the only downsides/issues, just a couple examples.
You can try following code:
Class WaiterUtility{
private Map<Class<? extends Food>, Waiter> waiters = new HashMap<>();
WaiterUtility() {
waiters.put(Appetizer.class, new AppetizerWaiter());
waiters.put(Entree.class, new EntreeWaiter());
waiters.put(Beverage.class, new BeverageWaiter());
waiters.put(Dessert.class, new DessertWaiter());
}
public serveItems(Food[] items)
{
for(Food aFood : items){
waiter.get(aFood.getClass()).serve(aFood);
}
}
private static abstract interface Waiter {
private void serve(Food aFood);
}
private static class AppetizerWaiter implements Waiter {
private void serve(Food aFood){
Appetizer appetizer = (Appetizer) aFood;
//somecode
}
}
private static class EntreeWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
private static class BeverageWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
private static class DessertWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
}
Try something similar to the following:
public serveItems(Food[] items)
{
for(Food aFood : items){
Class<?> foodClass = aFood.getClass(); // Get the food's class
Method serve = WaiterUtility.class.getMethod("serve", foodClass); // Get the method by name and argument types
try {
serve.invoke(this, aFood);
} catch (IllegalArgumentException e) { // Should never occur, we're matching it up.
} catch (IllegalAccessException e) { // Shouldn't occur, we're in the same class.
} catch (InvocationTargetException e) {
// Handle errors possibly thrown by the serve method.
}
}
Haven't tested this tho.
Note that you should however avoid this, it's terrible design.
package hf;
import javax.sound.midi.*;
public class BeatBox1
{
public static void main(String[] args)
{
BeatBox1 boom = new BeatBox1();
boom.go();
}
public void go()
{
try
{
Sequencer player = MidiSystem.getSequencer();
player.open();
Sequence seq = new Sequence(Sequence.PPQ,4);
Track track = seq.createTrack();
for(int i = 5;i<125;i+=5)
{
track.add(makeEvent(144,i,i));
track.add(makeEvent(128,i,i+2));
}
player.setSequence(seq);
player.start();
}
catch(Exception e)
{
System.out.println("Problem starting the BeatBox");
}
}
public static MidiEvent makeEvent(int onOff,int note,int time)
{
MidiEvent event = null;
try
{
ShortMessage a = new ShortMessage();
a.setMessage(onOff,1,note,100);
event = new MidiEvent(a,time);
return event;
}
catch(Exception e)
{
System.out.println("Error in creating Event.");
}
return event;
}
}
I found the above example code in a book. They recommend making the makeEvent method static. What is the reason?
The program runs correctly when makeEvent() is made non-static as well. Is there any performance gain or any advantage that can be obtained by making the method static?
Based on general OOP principles, a method is actually a 'behavior' which your class offers to public views of its instance. An instance is a real life version of the 'abstract existence' of the class. Now the important thing to understand here is that instance methods are behaviors that the class demonstrates. The behaviors of the class are tied to its 'state' ie. the variables or properties. For different values of state the same method of the class can show different behaviors i.e: operations performed.
Thus as a general rule: when a method offers a behavior that is dependent on the state of the instance and the behavior is unique to the class it should be non static and encapsulated in the class. Such a behavior should be exposed to the world only through a well defined contract, that normally is a public method or an interface of the class.
However when a method offers generic behavior not tied to any class or instance state nor influenced by the change in state it should be static i.e: independent of any class. Some examples are converting a given date to string, or loggin a message, or converting exceptions etc.
See what fits your case.
The reason is that you can access to static method directly without creating instance of class
It's more about style. makeEvent does not access any fields of BeatBox1, and static uses the compiler to ensure that claim.
As far as performance is concerned, there will be little to no difference. The complier will add a this as the first parameter of non-static methods, which is how fields are accessed, but this shouldn't make a real impact on performance.
I was wondering how would someone justify creating a GameManager while having the Single Responsibility Principle (SRP) in mind. concrete example: GameManager of a memory game (with the cards that you have to match). It obviously have many responsibilities: tracking of who's turn is it, switching between the turns, tracking when the game is finished, who the winner is and more...
When in doubt about exceeding object responsabilities. There is a concept related to SRP, cohesion, which is quite objective. In Konamiman's answer, the GameManager is 100% cohesive. It means all dependencies (instance fields) are used in all public methods.
0% would be the opposite:
class GameManager {
private int anInt;
private object aObj;
public void Foo() {
// Do anything but using anInt or aObj
}
}
If you find several cohesive components inside your object:
class GameManager {
private T1 obj1;
private T2 obj2;
public void Foo() {
T1.F1();
}
public void Goo() {
T2.G1();
}
}
The class should be split in two:
class GameManagerFoo {
private T1 obj1;
public void Foo() {
T1.F1();
}
}
class GameManagerGoo {
public void Goo() {
T2.G1();
}
}
Nice point #Jackl56: About property setters and getters you have 2 options. You could not take them into account or you could consider they lower your cohesion but to an acceptable level.
The key is that if you do things properly, the GameManager class will not directly have all the responsibilities you have mentioned. Instead, it will delegate these responsibilities into other classes, that will be passed to it by using some form of dependency injection. So you can say that the GameManager class has a single responsibility: to coordinate the work of the other classes; and has one single reason to change: to accommodate a change in the game logic that requires a new class to participate or to change the order of the interaction between classes.
A very simple example (sorry, C# syntax, but you get the idea):
public class GameManager
{
//constructor - note that the parameter types are interfaces, not classes
public GameManager(
IPlayerManager playerManager,
ITurnManager turnManager)
{
this.playerManager = playerManager;
this.turnManager = turnManager;
}
public void DoNextTurn()
{
var nextPlayer = playerManager.GetNextPlayer();
turnManager.ProcessTurn(nextPlayer);
//etc...
}
}
I would like to be able to write a Java class in one package which can access non-public methods of a class in another package without having to make it a subclass of the other class. Is this possible?
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.
Here's a clear use-case example with a reusable Friend class. The benefit of this mechanism is simplicity of use. Maybe good for giving unit test classes more access than the rest of the application.
To begin, here is an example of how to use the Friend class.
public class Owner {
private final String member = "value";
public String getMember(final Friend friend) {
// Make sure only a friend is accepted.
friend.is(Other.class);
return member;
}
}
Then in another package you can do this:
public class Other {
private final Friend friend = new Friend(this);
public void test() {
String s = new Owner().getMember(friend);
System.out.println(s);
}
}
The Friend class is as follows.
public final class Friend {
private final Class as;
public Friend(final Object is) {
as = is.getClass();
}
public void is(final Class c) {
if (c == as)
return;
throw new ClassCastException(String.format("%s is not an expected friend.", as.getName()));
}
public void is(final Class... classes) {
for (final Class c : classes)
if (c == as)
return;
is((Class)null);
}
}
However, the problem is that it can be abused like so:
public class Abuser {
public void doBadThings() {
Friend badFriend = new Friend(new Other());
String s = new Owner().getMember(badFriend);
System.out.println(s);
}
}
Now, it may be true that the Other class doesn't have any public constructors, therefore making the above Abuser code impossible. However, if your class does have a public constructor then it is probably advisable to duplicate the Friend class as an inner class. Take this Other2 class as an example:
public class Other2 {
private final Friend friend = new Friend();
public final class Friend {
private Friend() {}
public void check() {}
}
public void test() {
String s = new Owner2().getMember(friend);
System.out.println(s);
}
}
And then the Owner2 class would be like this:
public class Owner2 {
private final String member = "value";
public String getMember(final Other2.Friend friend) {
friend.check();
return member;
}
}
Notice that the Other2.Friend class has a private constructor, thus making this a much more secure way of doing it.
The provided solution was perhaps not the simplest. Another approach is based on the same idea as in C++: private members are not accessible outside the package/private scope, except for a specific class that the owner makes a friend of itself.
The class that needs friend access to a member should create a inner public abstract "friend class" that the class owning the hidden properties can export access to, by returning a subclass that implement the access-implementing methods. The "API" method of the friend class can be private so it is not accessible outside the class that needs friend access. Its only statement is a call to an abstract protected member that the exporting class implements.
Here's the code:
First the test that verifies that this actually works:
package application;
import application.entity.Entity;
import application.service.Service;
import junit.framework.TestCase;
public class EntityFriendTest extends TestCase {
public void testFriendsAreOkay() {
Entity entity = new Entity();
Service service = new Service();
assertNull("entity should not be processed yet", entity.getPublicData());
service.processEntity(entity);
assertNotNull("entity should be processed now", entity.getPublicData());
}
}
Then the Service that needs friend access to a package private member of Entity:
package application.service;
import application.entity.Entity;
public class Service {
public void processEntity(Entity entity) {
String value = entity.getFriend().getEntityPackagePrivateData();
entity.setPublicData(value);
}
/**
* Class that Entity explicitly can expose private aspects to subclasses of.
* Public, so the class itself is visible in Entity's package.
*/
public static abstract class EntityFriend {
/**
* Access method: private not visible (a.k.a 'friendly') outside enclosing class.
*/
private String getEntityPackagePrivateData() {
return getEntityPackagePrivateDataImpl();
}
/** contribute access to private member by implementing this */
protected abstract String getEntityPackagePrivateDataImpl();
}
}
Finally: the Entity class that provides friendly access to a package private member only to the class application.service.Service.
package application.entity;
import application.service.Service;
public class Entity {
private String publicData;
private String packagePrivateData = "secret";
public String getPublicData() {
return publicData;
}
public void setPublicData(String publicData) {
this.publicData = publicData;
}
String getPackagePrivateData() {
return packagePrivateData;
}
/** provide access to proteced method for Service'e helper class */
public Service.EntityFriend getFriend() {
return new Service.EntityFriend() {
protected String getEntityPackagePrivateDataImpl() {
return getPackagePrivateData();
}
};
}
}
Okay, I must admit it is a bit longer than "friend service::Service;" but it might be possible to shorten it while retaining compile-time checking by using annotations.
In Java it is possible to have a "package-related friendness".
This can be userful for unit testing.
If you do not specify private/public/protected in front of a method, it will be "friend in the package".
A class in the same package will be able to access it, but it will be private outside the class.
This rule is not always known, and it is a good approximation of a C++ "friend" keyword.
I find it a good replacement.
I think that friend classes in C++ are like inner-class concept in Java. Using inner-classes
you can actually define an enclosing class and an enclosed one. Enclosed class has full access to the public and private members of it's enclosing class.
see the following link:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Not using a keyword or so.
You could "cheat" using reflection etc., but I wouldn't recommend "cheating".
I think, the approach of using the friend accessor pattern is way too complicated. I had to face the same problem and I solved using the good, old copy constructor, known from C++, in Java:
public class ProtectedContainer {
protected String iwantAccess;
protected ProtectedContainer() {
super();
iwantAccess = "Default string";
}
protected ProtectedContainer(ProtectedContainer other) {
super();
this.iwantAccess = other.iwantAccess;
}
public int calcSquare(int x) {
iwantAccess = "calculated square";
return x * x;
}
}
In your application you could write the following code:
public class MyApp {
private static class ProtectedAccessor extends ProtectedContainer {
protected ProtectedAccessor() {
super();
}
protected PrivateAccessor(ProtectedContainer prot) {
super(prot);
}
public String exposeProtected() {
return iwantAccess;
}
}
}
The advantage of this method is that only your application has access to the protected data. It's not exactly a substitution of the friend keyword. But I think it's quite suitable when you write custom libraries and you need to access protected data.
Whenever you have to deal with instances of ProtectedContainer you can wrap your ProtectedAccessor around it and you gain access.
It also works with protected methods. You define them protected in your API. Later in your application you write a private wrapper class and expose the protected method as public. That's it.
If you want to access protected methods you could create a subclass of the class you want to use that exposes the methods you want to use as public (or internal to the namespace to be safer), and have an instance of that class in your class (use it as a proxy).
As far as private methods are concerned (I think) you are out of luck.
I agree that in most cases the friend keyword is unnecessary.
Package-private (aka. default) is sufficient in most cases where you have a group of heavily intertwined classes
For debug classes that want access to internals, I usually make the method private and access it via reflection. Speed usually isn't important here
Sometimes, you implement a method that is a "hack" or otherwise which is subject to change. I make it public, but use #Deprecated to indicate that you shouldn't rely on this method existing.
And finally, if it really is necessary, there is the friend accessor pattern mentioned in the other answers.
A method I've found for solving this problem is to create an accessor object, like so:
class Foo {
private String locked;
/* Anyone can get locked. */
public String getLocked() { return locked; }
/* This is the accessor. Anyone with a reference to this has special access. */
public class FooAccessor {
private FooAccessor (){};
public void setLocked(String locked) { Foo.this.locked = locked; }
}
private FooAccessor accessor;
/** You get an accessor by calling this method. This method can only
* be called once, so calling is like claiming ownership of the accessor. */
public FooAccessor getAccessor() {
if (accessor != null)
throw new IllegalStateException("Cannot return accessor more than once!");
return accessor = new FooAccessor();
}
}
The first code to call getAccessor() "claims ownership" of the accessor. Usually, this is code that creates the object.
Foo bar = new Foo(); //This object is safe to share.
FooAccessor barAccessor = bar.getAccessor(); //This one is not.
This also has an advantage over C++'s friend mechanism, because it allows you to limit access on a per-instance level, as opposed to a per-class level. By controlling the accessor reference, you control access to the object. You can also create multiple accessors, and give different access to each, which allows fine-grained control over what code can access what:
class Foo {
private String secret;
private String locked;
/* Anyone can get locked. */
public String getLocked() { return locked; }
/* Normal accessor. Can write to locked, but not read secret. */
public class FooAccessor {
private FooAccessor (){};
public void setLocked(String locked) { Foo.this.locked = locked; }
}
private FooAccessor accessor;
public FooAccessor getAccessor() {
if (accessor != null)
throw new IllegalStateException("Cannot return accessor more than once!");
return accessor = new FooAccessor();
}
/* Super accessor. Allows access to secret. */
public class FooSuperAccessor {
private FooSuperAccessor (){};
public String getSecret() { return Foo.this.secret; }
}
private FooSuperAccessor superAccessor;
public FooSuperAccessor getAccessor() {
if (superAccessor != null)
throw new IllegalStateException("Cannot return accessor more than once!");
return superAccessor = new FooSuperAccessor();
}
}
Finally, if you'd like things to be a bit more organized, you can create a reference object, which holds everything together. This allows you to claim all accessors with one method call, as well as keep them together with their linked instance. Once you have the reference, you can pass the accessors out to the code that needs it:
class Foo {
private String secret;
private String locked;
public String getLocked() { return locked; }
public class FooAccessor {
private FooAccessor (){};
public void setLocked(String locked) { Foo.this.locked = locked; }
}
public class FooSuperAccessor {
private FooSuperAccessor (){};
public String getSecret() { return Foo.this.secret; }
}
public class FooReference {
public final Foo foo;
public final FooAccessor accessor;
public final FooSuperAccessor superAccessor;
private FooReference() {
this.foo = Foo.this;
this.accessor = new FooAccessor();
this.superAccessor = new FooSuperAccessor();
}
}
private FooReference reference;
/* Beware, anyone with this object has *all* the accessors! */
public FooReference getReference() {
if (reference != null)
throw new IllegalStateException("Cannot return reference more than once!");
return reference = new FooReference();
}
}
After much head-banging (not the good kind), this was my final solution, and I very much like it. It is flexible, simple to use, and allows very good control over class access. (The with reference only access is very useful.) If you use protected instead of private for the accessors/references, sub-classes of Foo can even return extended references from getReference. It also doesn't require any reflection, so it can be used in any environment.
I prefer delegation or composition or factory class (depending upon the issue that results in this problem) to avoid making it a public class.
If it is a "interface/implementation classes in different packages" problem, then I would use a public factory class that would in the same package as the impl package and prevent the exposure of the impl class.
If it is a "I hate to make this class/method public just to provide this functionality for some other class in a different package" problem, then I would use a public delegate class in the same package and expose only that part of the functionality needed by the "outsider" class.
Some of these decisions are driven by the target server classloading architecture (OSGi bundle, WAR/EAR, etc.), deployment and package naming conventions. For example, the above proposed solution, 'Friend Accessor' pattern is clever for normal java applications. I wonder if it gets tricky to implement it in OSGi due to the difference in classloading style.
I once saw a reflection based solution that did "friend checking" at runtime using reflection and checking the call stack to see if the class calling the method was permitted to do so. Being a runtime check, it has the obvious drawback.
As of Java 9, modules can be used to make this a non-issue in many cases.