Make an enum INSTANCE private - java

I am using an enum singletom pattern like this:
public enum LicenseLoader implements ClientLicense {
INSTANCE;
/**
* #return an instance of ClientLicense
*/
public static ClientLicense getInstance() {
return (ClientLicense)INSTANCE;
}
...rest of code
}
Now I want to return the Interface and hide the fact that we are actually using an enum at all. I want the client to use getInstance() and not LicenseLoader.INSTANCE as one day I may decide to use a different pattern if necessary.
Is is possible to make INSTANCE private to the enum?

What about making a public interface and private enum that implements said interface, with a singleton INSTANCE constant?
So, something like this (all in one class for brevity):
public class PrivateEnum {
public interface Worker {
void doSomething();
}
static private enum Elvis implements Worker {
INSTANCE;
#Override public void doSomething() {
System.out.println("Thank you! Thank you very much!");
}
}
public Worker getWorker() {
return Elvis.INSTANCE;
}
}
This way, you're not exposing Elvis.INSTANCE (or even enum Elvis at all), using an interface to define your functionality, hiding all implementation details.

All enum constants are accessible. For instance through deserialisation or the enum-specific reflective methods.
As always, I strongly suggest avoiding singletons.

Related

How to make sure that there is just one instance of class in JVM?

I am developing a design pattern, and I want to make sure that here is just one instance of a class in Java Virtual Machine, to funnel all requests for some resource through a single point, but I don't know if it is possible.
I can only think of a way to count instances of a class and destroy all instance after first is created.
Is this a right approach? If not, is there any other way?
Use the singleton pattern. The easiest implementation consists of a private constructor and a field to hold its result, and a static accessor method with a name like getInstance().
The private field can be assigned from within a static initializer block or, more simply, using an initializer. The getInstance() method (which must be public) then simply returns this instance,
public class Singleton {
private static Singleton instance;
/**
* A private Constructor prevents any other class from
* instantiating.
*/
private Singleton() {
// nothing to do this time
}
/**
* The Static initializer constructs the instance at class
* loading time; this is to simulate a more involved
* construction process (it it were really simple, you'd just
* use an initializer)
*/
static {
instance = new Singleton();
}
/** Static 'instance' method */
public static Singleton getInstance() {
return instance;
}
// other methods protected by singleton-ness would be here...
/** A simple demo method */
public String demoMethod() {
return "demo";
}
}
Note that the method of using “lazy evaluation” in the getInstance() method (which
is advocated in Design Patterns), is not necessary in Java because Java already uses “lazy
loading.” Your singleton class will probably not get loaded unless its getInstance()
is called, so there is no point in trying to defer the singleton construction until it’s needed
by having getInstance() test the singleton variable for null and creating the singleton
there.
Using this class is equally simple: simply get and retain the reference, and invoke methods on it:
public class SingletonDemo {
public static void main(String[] args) {
Singleton tmp = Singleton.getInstance();
tmp.demoMethod();
}
}
Some commentators believe that a singleton should also provide a public final
clone() method that just throws an exception, to avoid subclasses that “cheat” and
clone() the singleton. However, it is clear that a class with only a private constructor
cannot be subclassed, so this paranoia does not appear to be necessary.
That's the well known Singleton pattern: you can implement this as follows:
public class SingletonClass {
//this field contains the single instance every initialized.
private static final instance = new SingletonClass();
//constructor *must* be private, otherwise other classes can make an instance as well
private SingletonClass () {
//initialize
}
//this is the method to obtain the single instance
public static SingletonClass getInstance () {
return instance;
}
}
You then call for the instance (like you would constructing a non-singleton) with:
SingletonClass.getInstance();
But in literature, a Singleton is in general considered to be a bad design idea. Of course this always somewhat depends on the situation, but most programmers advice against it. Only saying it, don't shoot on the messenger...
There is a school of thought that considers the Singleton pattern to in fact be an anti-pattern.
Considering a class A that you only wish to have one of, then an alternative is to have a builder or factory class that itself limits the creation of the number of objects of Class A, and that could be by a simple counter.
The advantage is that Class A no longer needs to worry about that, it concentrates on its real purpose. Every class that uses it no longer has to worry about it being a singleton either (no more getInstance() calls).
You want the Singleton pattern. There is an excellent discussion of how to implement this properly. If you do this right, there will only ever be one instance of the class.
Essentially what you are going to do is create a class, hold a single instantiated object of that class at the static level, and provide a static accessor to get it (getInstance() or similar). Make the constructor final so people can't create their own instances out of the blue. That link above has plenty of great advice on how to do this.
Use enum. In Java enum is the only true way to create a singleton. Private constructors can be still called through reflection.
See this StackOverflow question for more details:
Implementing Singleton with an Enum (in Java)
Discussion:
http://javarevisited.blogspot.com/2012/07/why-enum-singleton-are-better-in-java.html
I can only think of a way to count instances of a class and destroy all instance after first is created. Is this a right approach ? If not, is there any other way ?
The correct technical approach is to declare all of the constructors for the class as private so that instances of the class can only be created by the class itself. Then you code the class only ever create one instance.
Other Answers show some of the ways to implement this, according to the "Singleton" design pattern. However, implementing a singleton like this has some drawbacks, including making it significantly harder to write unit tests.
I prefer lazy singleton class, which overrides readResolve method.
For Serializable and Externalizable classes, the readResolve method allows a class to replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized.
Lazy singleton using /Initialization-on-demand_holder_idiom:
public final class LazySingleton {
private LazySingleton() {}
public static LazySingleton getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final LazySingleton INSTANCE = new LazySingleton();
}
private Object readResolve() {
return LazyHolder.INSTANCE;
}
}
Key notes:
final keyword prohibits extension of this class by sub-classing
private constructor prohibits direct object creation with new operator in caller classes
readResolve prohibits creation of multiple instances of class during object de-serialization
For that you need to use singleton pattern, I am just posting a demo code for that that may useful for your understanding.
E.g: If I want only one object for this Connect class:
public final class Connect {
private Connect() {}
private volatile static Connect connect = null;
public static Connect getinstance() {
if(connect == null) {
synchronized (Connect.class) {
connect = new Connect();
}
}
return connect;
}
}
Here the constructor is private, so no one can use new keyword to make a new instance.
class A{
private A(){
}
public static A creator(A obj){
A ob=new A();
return ob;
}
void test(){
System.out.println("The method is called");
}
}
class Demo{
public static void main(String[] args){
A ob=null;
ob=A.creator(ob);
ob.test();
}
}

advantage of enum over class in singleton pattern

I recently came to know that enum is a more effcient way to implement singleton.
Singleton with enum:
public enum Singleton{
INSTANCE;
public void doStuff(){
//......
}
public void doMoreStuff(){
//......
}
}
Singleton with class:
public class Singleton{
private static final INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
public void doStuff(){
//......
}
public void doMoreStuff(){
//......
}
}
QUESTION: What are the possible advantages or disadvantages of using enum over class to implement the singleton ?
As explained by Joshua Bloch, the two approaches are functionally identical if your singleton is not serializable. Although you may wish to add code to your private Singleton constructor to prevent reflection being used to create a second instance.
If your singleton is serializable, then the enum approach will provide all the necessary plumbing for free, whereas with the static field approach, you have to add that yourself.
In my view, there is no downside to adopting the enum approach.
I believe enums are the best way to create singletons. If you are looking for downsides
It is not possible to have lazy load with enums
If you serialize and deserialize the enum, the members in the enums are reset to default value.
If you change your mind and want to make it non-singleton, It is easy with double checked synchronized singleton.

Java - make class static instead of one instance of it

Let's say i have a class, and I made only one instance of it and i don't need more than that.
Should i just make the class static ? (not the class itself but the functions and the variables).
In the example below should i make the class static if i won't make more than one instance of it ?
public class Foo {
int num1;
int num2;
public void func() {
// Something in here
}
}
public static void main(String[] args) {
Foo bar = new Foo(); //I don't need more than one instance of that class.
}
If your class has no state, say:
class NoState {
static int sum(int i1, int i2) { return i1 + i2; }
}
then it makes sense to use static methods.
If you must ensure that there is only one instance of your class, then you could use a singleton, but be careful: global state can be evil.
Not as bad as a singleton, you could use static fields/methods: it can be useful is some situations but should not be abused.
In any other situations (= most of the time), just use normal instance variables/methods.
You can use an enum to define a singleton.
public enum Foo {
INSTANCE;
int num1;
int num2;
public void func() {
// Something in here
}
}
public static void main(String[] args) {
Foo bar = Foo.INSTANCE;
}
However, this is only need if you want to enforce one instance. Otherwise, I would just use new Foo(); and call it only once, if you only need one.
You can use Singleton. However, make sure if Singleton is what is really required - sometimes singletons gets overused where simple class with static methods might suffice. There are many ways to create singleton as explained What is an efficient way to implement a singleton pattern in Java?
Note that with Java 5, enum is the preferred way to create singleton.
You say that i don't need more than that so my answer is that not make more than one and if you really like to enforce the instance that it should be only one for class then use the enum best way to implement the singleton in java
for example in datasource one really needs singleton
public enum UserActivity {
INSTANCE;
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
private UserActivity() {
this.dataSource = MysqlDb.getInstance().getDataSource();
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
}
public void dostuff() {
...
}
}
and if you really need that then use it otherwise go with your current logic
A class that must be instantiated once and only once, is called a singleton. That knowledge should help you narrow down your search for information. To give you a head start:
Difference between static class and singleton pattern?
Why use a singleton instead of static methods?
Basically static methods and fields means that you don't need any instances of the class.
In you case you need 'singleton' class, you can either use enum or make it a singleton by yourself, using the specific set of rules.
It really depends on the scope of your application. If you want this object to be used as a singleton you would provide a static method to get the one and only instance of the class.
public class Foo
{
private static Foo instance ....
private Foo()
{
.....
}
public static Foo getInstance()
{
return instance;
}
}
If you plan to use a framework like spring you would just add one object to the application context.
<bean class="....Foo" id="fooInstance" scope="singleton">
....
</bean>
But maybe, you can refractor this class to hold only static methods. Then you can mark the class as final and provide a private constructor.
public final class Utils
{
private Utils(){}
public static .... doFoo(....)
{
....
}
}

implement a singleton design pattern as a template

Here is the question:
Implement a singleton design pattern as a template such that, for any given class
Foo, you can call Singleton::instance() and get a pointer to an instance of a singleton
of type Foo. Assume the existence of a class Lock which has acquire() and release()
methods. How could you make your implementation thread safe and exception safe?
My analysis:
as Joshua Bloch points out in "effective java", the better ways to implement
a singleton class is enum and public static factory method. Combining volatile
and synchronized is the way I know to make it thread safe and lazy initialization
as follows
public class myS{
private static volatile final _ins = null;
private myS(){};
public static myS getIns(){
synchronized(){
if(_ins==null) _ins = new myS();
}
return _ins;
}
}
At this moment, I am a little confused to make a singleton template. My understanding is that we either have an interface with generic type or an abstract class. As long as the clients implement them, they are singleton. So, my guess solution is as follows:
public interface singleton<T>{
public T instance();
}
public class Foo implements singleton<T>{
private static volatile final Foo _ins = null;
public static Foo instance(){
synchronized(this)
if(_ins==null){
_ins = new Foo();
}
}
}
}
The easiest way to get singleton functionality is to use a Dependancy Injection (DI) framework like Spring. There are plenty of other benefits gained by using DI as well.
'singleton' does not fit with 'template'. It is a kind of contradiction. If think you will be better off implementing enums as following
public enum MySingleton1 {
;
public static void MethodA() { ... };
}
public enum MySingleton2 {
;
public static int MethodB() { ... };
}
EDIT
A solution without enums would be:
public interface singletonMarker{};
public final class MySingleton1() extends singletonMarker {
public static final MySingleton1 INSTANCE = new MySingleton1();
private MySingleton1() {};
public synchronized int mySyncMethod() { ... };
}
Usage
MySingleton1.INSTANCE.mySyncMethod();
The interface is only acting as marker, but it is not really necessary.

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

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.

Categories