Here is my sample abstract singleton class:
public abstract class A {
protected static A instance;
public static A getInstance() {
return instance;
}
//...rest of my abstract methods...
}
And here is the concrete implementation:
public class B extends A {
private B() { }
static {
instance = new B();
}
//...implementations of my abstract methods...
}
Unfortunately I can't get the static code in class B to execute, so the instance variable never gets set. I have tried this:
Class c = B.class;
A.getInstance() - returns null;
and this
ClassLoader.getSystemClassLoader().loadClass("B");
A.getInstance() - return null;
Running both these in the eclipse debugger the static code never gets executed. The only way I could find to get the static code executed is to change the accessibility on B's constructor to public, and to call it.
I'm using sun-java6-jre on Ubuntu 32bit to run these tests.
Abstract Singleton? Doesn't sound viable to me. The Singleton pattern requires a private constructor and this already makes subclassing impossible. You'll need to rethink your design. The Abstract Factory pattern may be more suitable for the particular purpose.
You are trying to get an abstract class play two very different roles:
the abstract factory role for a
(singleton) service that can have
multiple substitutable
implementations,
the service
interface role,
and on top of that you also want the service to be singleton and enforce 'singletoness' on the entire family of classes, for some reason you aren't considering caching the service instances.
Somebody (I would) will say it smells very bad, for multiple reasons
it violates separation of concerns,
singletons make unit testing impossible",
etc.
Somebody else will say it's ok-ish, it doesn't need a lot of different infrastructure and has kind of fluent-ish interface that you see in some very common third party (legacy) Java API.
The bad part is demanding the children to select what implementation should the parent factory method return.
That responsibility should be pushed up and centralised into the abstract superclass. Otherwise you are mixing together patterns that are used in very different contexts, Abstract Factory (parent decide what family of classes clients are going to get) and Factory Method (children factories select what the clients will get).
Factory Method is also not practically possible because you can't override static methods, nor constructors.
There are some (ugly) ways to achieve your objective though:
public abstract class A{
public static A getInstance(...){
if (...)
return B.getInstance();
return C.getInstance();
}
public abstract void doSomething();
public abstract void doSomethingElse();
}
public class B extends A{
private static B instance=new B();
private B(){
}
public static B getInstance(){
return instance;
}
public void doSomething(){
...
}
...
}
//do similarly for class C
The parent could also use reflection, cache instances, etc.
A more test and extension friendly solution is simply standard separation of concerns. The children aren't going to be singleton anymore per se, but you package them into some internal package that you will document as "private" and a public abstract parent in an external package will handle caching or pooling of children instances, enforcing whatever instantiation policy is required on these classes.
A.getInstance() will never call a derived instance since it's statically bound.
I would separate the creation of the object from the actual object itself and create an appropriate factory returning a particular class type. It's not clear how you'd parameterise that, given your example code - is it parameterised via some argument, or is the class selection static ?
You may want to rethink the singleton, btw. It's a common antipattern and makes testing (in particular) a pain, since classes under test will provide their own instance of that class as a singleton. You can't provide a dummy implementation nor (easily) create a new instance for each test.
In addition to problems others have pointed out, having the instance field in A means that you can only have one singleton in the entire VM. If you also have:
public class C extends A {
private C() { }
static {
instance = new C();
}
//...implementations of my abstract methods...
}
... then whichever of B or C gets loaded last will win, and the other's singleton instance will be lost.
This is just a bad way to do things.
Singletons are kind of yucky. Abstract insists on inheritance which you more often than not want to avoid if possible. Overall I'd rethink if what you are trying to do is the simplest possible way, and if so, then be sure to use a factory and not a singleton (singletons are notoriously hard to substitute in unit tests whereas factories can be told to substitute test instances easily).
Once you start looking into implementing it as a factory the abstract thing will sort itself out (either it will clearly be necessary or it may factor out easily in place of an interface).
I found a better way to use Singleton in abstract class, which use a static Map to maintain the instance of subclass.
public abstract class AbstractSingleton {
private static Map<String, AbstractSingleton> registryMap = new HashMap<String, AbstractSingleton>();
AbstractSingleton() throws SingletonException {
String clazzName = this.getClass().getName();
if (registryMap.containsKey(clazzName)) {
throw new SingletonException("Cannot construct instance for class " + clazzName + ", since an instance already exists!");
} else {
synchronized (registryMap) {
if (registryMap.containsKey(clazzName)) {
throw new SingletonException("Cannot construct instance for class " + clazzName + ", since an instance already exists!");
} else {
registryMap.put(clazzName, this);
}
}
}
}
#SuppressWarnings("unchecked")
public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz) throws InstantiationException, IllegalAccessException {
String clazzName = clazz.getName();
if (!registryMap.containsKey(clazzName)) {
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
T instance = clazz.newInstance();
return instance;
}
}
}
return (T) registryMap.get(clazzName);
}
public static AbstractSingleton getInstance(final String clazzName)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (!registryMap.containsKey(clazzName)) {
Class<? extends AbstractSingleton> clazz = Class.forName(clazzName).asSubclass(AbstractSingleton.class);
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
AbstractSingleton instance = clazz.newInstance();
return instance;
}
}
}
return registryMap.get(clazzName);
}
#SuppressWarnings("unchecked")
public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz, Class<?>[] parameterTypes, Object[] initargs)
throws SecurityException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException, InstantiationException, IllegalAccessException {
String clazzName = clazz.getName();
if (!registryMap.containsKey(clazzName)) {
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
Constructor<T> constructor = clazz.getConstructor(parameterTypes);
T instance = constructor.newInstance(initargs);
return instance;
}
}
}
return (T) registryMap.get(clazzName);
}
static class SingletonException extends Exception {
private static final long serialVersionUID = -8633183690442262445L;
private SingletonException(String message) {
super(message);
}
}
}
From: https://www.cnblogs.com/wang9192/p/3975748.html
Related
I want to create a wrapper class over another class so that it hides the functionality of wrapped class and also the wrapper provides certain methods of its own.
For example, lets say we have class A as
public class A{
void method1(){ ... do something ... }
void method2(){ ... do something ... }
void method3(){ ... do something ... }
}
Now I want another class B which wraps class A, so that it has its own methods, and also if someone asks method of class A, it should delegate it to class A.
public class B{
// if someone asks method1() or method2() or method3() ... it should delegate it to A
// and also it has own methods
void method4(){ ... do something ... }
void method5(){ ... do something ... }
}
I can't use inheritance (i.e B extends A) because its not easy with my use case (where A has concrete constructor with some parameters which we can't get ... but we can get the object of A).
I can't simply delegate each function in A using object of A (because there are several functions in A)
Is there any other way to obtain class B with said restrictions?
Important Note: Class A is handled by someone else. We can't change any part of it.
What you have described is a Decorator pattern coined by GOF. There is plenty of sources on the Internet about it. It is similar to the Proxy pattern (as in the answer of Pavel Polivka) but the intent is different. You need the Decorator pattern:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. sourcemaking.com
As you have written in a comment
class A inherits from single interface containing several methods
I assume A implements AIntf and contains all the methods you want.
public class BDecorator implements AIntf {
private A delegate;
private BDecorator(A delegate) {
this.delegate = delegate;
}
void method1(){ delegate.method1(); }
// ...
void method4(){ /* something new */ }
There are several functions in A, and I don't want to do tedious work of writing each method explicitly in B.
Java is a verbose language. However, you don't need to do this by hand, every decent IDE provides automatic generation of delegate methods. So it will take you 5 seconds for any amount of methods.
The class A is not in my control, I mean someone might update its method signatures, In that case I need to watch over class A and made changes to my class B.
If you create B you are responsible for it. You at least notice if anything changed. And once again, you can re-generate the changed method with the help of an IDE in an instant.
This can be easily done with CGLIB but will require few modifications. Consider if those modifications may not be harder to do that the actual delegation of the methods.
You need to extend the classes, this can be done by adding the no arg constructor to class A, we will still delegate all the methods so do not worry about unreachable params, we are not worried about missing data, we just want the methods
You need to have CGLIB on you classpath cglib maven, maybe you already have it
Than
A would look like
public class A {
private String arg = "test";
public A() {
// noop just for extension
}
public A(String arg) {
this.arg = arg;
}
public void method1() {
System.out.println(arg);
}
}
B would look like
public class B extends A implements MethodInterceptor {
private A delegate;
private B(A delegate) {
this.delegate = delegate;
}
public static B createProxy(A obj) {
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new B(obj));
B proxifiedObj = (B) e.create();
return proxifiedObj;
}
void method2() {
System.out.println("a");
}
#Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) { return m.invoke(this, objects); }
Object res = method.invoke(delegate, objects);
return res;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
That you can do
MyInterface b = B.createProxy(new A("delegated"));
b.method1(); // will print delegated
This is not very nice solution and you probably do not need it, please consider refactoring your code before doing this. This should be used only in very specific cases.
Is there any way to create object outside the class in singleton design pattern?
public class Test {
private Test() {}
private static final Test t=new Test();
public static Test getTest() {
return t;
}
}
Although the singleton pattern doesn't really work if you want to do this, I can still tell you what to do. I guess you mean "Get an arbitary instance outside the singleton class". Now you can add the following method:
public Test getNewTest (/*You can add parameters if you like*/) {
return enw Test();
}
But this really violates the singleton pattern. You use the singleton pattern because you just want one instance of it. But now you can create multiple instance of it!
Not sure what you mean by "outside of the class" but this public access static method will create your object one and only one time.
class MySingletonObject {
private static MySingletonObject instance = null;
private MySingletonObject() {};
public static MySingletonObject getInstance() {
if (instance == null) {
instance = new MySingletonObject();
}
return instance;
}
}
A quick search on Singleton Design Pattern tells us that it is used so that we are sure that only one instance of a class is created.
Singleton Pattern is useful when exactly one object is needed to coordinate the actions across the system. The object must also be responsible for creation, initialization, access, and enforcement of this design pattern.
As Sweeper answered, it is possible to create the object outside of its class. If we make this possible, then we will not sure anymore if the class still follows the Singleton Design Pattern. Creating the object outside of its class violates the Design Pattern. It will not be a Singleton anymore.
TLDR; Yes, there is a way to create the object outside its class, however it will not be a Singleton anymore.
By the name singleton it signifies only one object, mainly used to create a jdbc connection.. Where only one connection can be fetched at a time.Making singleton class public i.e. Constructor doesn't make any sense as it can be instantiated via any other class.. That's why a factory method is developed which returns only one object(new one for first time and existed for further attempts).Here you're restricting the instantiation which is the basic rule while developing a singleton class.
This is just show that it is possible to create object outside the singleton class, but this would not be according to the singleton pattern:
Test.java
public class Test {
private Test() {
}
private static Test t = null;
public static Test getTest() {
if (t == null) {
synchronized (Test.class) {
if (t == null) {
try {
t = Util.createAndGetTest();
} catch (Exception e) {
throw new RuntimeException(
"Exception creating Test object", e);
}
}
}
}
return t;
}
}
Util.java
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Util {
public static Test createAndGetTest() throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException,
InstantiationException {
Constructor<Test> constructor = Test.class.getDeclaredConstructor();
constructor.setAccessible(true);
Test t = constructor.newInstance();
return t;
}
}
Main.java
public class Main {
public static void main(String[] args) {
Test t = Test.getTest();
}
}
I've a parameterized interface:
public interface MyInterface<T> {
void run(T e);
}
And classes implementing the interface:
public class MyClass1 implements MyInterface<SomeOtherClass1> {
public void run(SomeOtherClass1 e) {
// do some stuff with e
}
}
public class MyClass2 implements MyInterface<SomeOtherClass2> {
public void run(SomeOtherClass2 e) {
// do some stuff with e
}
}
The number of different MyClass*X* is known and exhaustive, and there is only one instance of each MyClass*X*, so I would like to use an enum:
public enum MyEnum {
MY_CLASS_1,
MY_CLASS_2;
}
To be able to use MyEnum.MY_CLASS_1.run(someOtherClass1); for example (I would then have every instance of MyInterface in one same place). Is it even possible (and if yes, how)? Because I'm quite stuck for now...
What I tried yet:
public enum MyEnum {
MY_CLASS_1(new MyClass1()),
MY_CLASS_2(new MyClass2());
private MyInterface<?> instance;
private MyEnum(MyInterface<?> instance) {
this.instance = instance;
}
public void run(/* WhichType? */ e) {
instance.run(e);
}
}
In the above method, when using the type Object for the e parameter:
public void run(Object e) {
instance.run(e);
// ^^^
// The method run(capture#3-of ?) in the type MyInterface<capture#3-of ?> is not applicable for the arguments (Object)
}
The problem I think is with that private MyInterface<?> instance field: I need to know how is the instance parameterized, using something like private MyInterface<T> instance, but I can't find a working solution...
In short, I'm stuck ;)
PS: since the run methods bodies can be quite long, I'm trying to avoid anonymous classes within the enum:
public enum MyEnum {
MY_CLASS_1 {
/* any method, etc. */
},
MY_CLASS_2 {
/* any method, etc. */
},
}
MyEnum would then become totally unreadable.
It's not possible. That's one of the enum limitations I find most annoying, but all you can do is try to work around it (as you would have done in Java pre-5.0).
Only the enum itself can implement the interface and the generics must be specified at the enum level, so only Object or some common interface for those two would apply in your case.
Declaring any aspect that you want to treat polymorphically (the run() method, in your example) inside the enum itself (and overriding the behavior in each constant) is usually the best workaround. Of course, you need to loosen up your type safety requirements.
If you want to keep those strategies separated, you still need a run(Object) method inside the enum and that will be defined in each constant with some explicit cast, since you simply cannot have different method signatures per enum instance (or even if you can, they won't be visible as such from the outside).
A hint on how to trick the compiler, if you really want to do that rather than a redesign or explicit casts for each instance:
enum MyEnum implements MyInterface<Object> {
MY_CLASS_1(new MyClass1()),
MY_CLASS_2(new MyClass2());
// you may also drop generics entirely: MyInterface delegate
// and you won't need that cast in the constructor any more
private final MyInterface<Object> delegate;
MyEnum(MyInterface<?> delegate) {
this.delegate = (MyInterface<Object>) delegate;
}
#Override
public void run(Object e) {
delegate.run(e);
}
}
The above will work and you'll get a ClassCastException (as expected) if you try to use MyEnum.MY_CLASS_1.run() with something other than SomeOtherClass1.
As Costi points out, enums themselves can't be generic. However I think I can identify where you went wrong in your design:
There is only one instance of each MyClassX, so I would like to use
an enum:
public enum MyEnum {
MY_CLASS_1,
MY_CLASS_2;
}
You're saying that each of these classes is a singleton. So they should in fact each be an enum:
public enum MyClass1 implements MyInterface<SomeOtherClass1> {
INSTANCE;
#Override
public void run(SomeOtherClass1 e) {
// do some stuff with e
}
}
public enum MyClass2 implements MyInterface<SomeOtherClass2> {
INSTANCE;
#Override
public void run(SomeOtherClass2 e) {
// do some stuff with e
}
}
This makes more sense because if you think about it, you don't need to enumerate these two implementations, so there's no need for them to live together. It's enough to use Josh Bloch's enum pattern for each of them individually.
I have a class from another library that is closed-source, but I want to be able to use an interface for it. The reason being that I don't want to do instanceof checks or null-checks everywhere, but I also don't want to extend the existing class.
For example, let's say I have this code:
public class Example {
// QuietFoo is from another library that I can't change
private static QuietFoo quietFoo;
// LoudFoo is my own code and is meant to replace QuietFoo
private static LoudFoo loudFoo;
public static void main(String[] args) {
handle(foo);
}
private static void handle(Object foo) {
if (foo instanceof QuietFoo)
((QuietFoo) foo).bar();
else if (foo instanceof LoudFoo)
((LoudFoo) foo).bar();
}
}
I can't change QuietFoo:
public class QuietFoo {
public void bar() {
System.out.println("bar");
}
}
But I can change LoudFoo:
public class LoudFoo {
public void bar() {
System.out.println("BAR!!");
}
}
The problem is, there may be many other implementations of bar in many classes, and there may be more methods than just bar, so not only would my handle method get slow and ugly with lots of instanceof statements, but I would have to write one of these handle methods for each method on QuietFoo and LoudFoo. Extending isn't a viable solution because it violates the whole is-a contract since LoudFoo is not a QuietFoo.
Basically, given Foo:
public interface Foo {
void bar();
}
How can I make QuietFoo implement Foo without changing its source so I don't have to do casting and instanceof calls everywhere in my code?
There are two approaches:
Using an adapter pattern
Using Proxy
The adapter approach will be simpler but less flexible, and the Proxy approach will be more complex but more flexible. Even though the Proxy approach is more complex, that complexity is all restricted to a couple of classes.
Adapter
The adapter pattern is simple. For your example, it would just be one class, like so:
public class QuietFooAdapter implements Foo {
private QuietFoo quietFoo;
public QuietFooAdapter(QuietFoo quietFoo) {
this.quietFoo = quietFoo;
}
public void bar() {
quietFoo.bar();
}
}
Then to use it:
Foo foo = new QuietFooAdapter(new QuietFoo());
foo.bar();
This is good, but if you have more than one class to make an adapter for, this can be tedious since you'll need a new adapter for each class you have to wrap.
Java's Proxy Class
Proxy is a native Java class that's part of the reflection libraries that will allow you to create a more generic, reflective solution. It involves 3 parts:
The interface (in this case, Foo)
The InvocationHandler
Creation of the proxy (Proxy.newProxyInstance)
We already have the interface, so we're fine there.
The InvocationHandler is where we do our "auto-adapting" via reflection:
public class AdapterInvocationHandler implements InvocationHandler {
private Object target;
private Class<?> targetClass;
public AdapterInvocationHandler(Object target) {
this.target = target;
targetClass = target.getClass();
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Method targetMethod = targetClass.getMethod(method.getName(), method.getParameterTypes());
if (!method.getReturnType().isAssignableFrom(targetMethod.getReturnType()))
throw new UnsupportedOperationException("Target (" + target.getClass().getName() + ") does not support: " + method.toGenericString());
return targetMethod.invoke(target, args);
} catch (NoSuchMethodException ex) {
throw new UnsupportedOperationException("Target (" + target.getClass().getName() + ") does not support: " + method.toGenericString());
} catch (IllegalAccessException ex) {
throw new UnsupportedOperationException("Target (" + target.getClass().getName() + ") does not declare method to be public: " + method.toGenericString());
} catch (InvocationTargetException ex) {
// May throw a NullPointerException if there is no target exception
throw ex.getTargetException();
}
}
}
The important code here is in the try block. This will handle the process of adapting any method calls that are called on the proxy to the inner target object. If a method is called on the interface that isn't supported (non-public, wrong return type, or just flat out doesn't exist), then we throw an UnsupportedOperationException. If we catch an InvocationTargetException, we rethrow the exception that caused it via InvocationTargetException.getTargetException. This occurs when the method we called reflectively throws an exception. Java wraps it in a new exception and throws that new exception.
Next, we need something to create the adapters:
public class AdapterFactory {
public static <T> T createAdapter(Object target, Class<T> interfaceClass) {
if (!interfaceClass.isInterface())
throw new IllegalArgumentException("Must be an interface: " + interfaceClass.getName());
return (T) Proxy.newProxyInstance(null, new Class<?>[] { interfaceClass }, new AdapterInvocationHandler(target));
}
}
You could also nest the AdapterInvocationHandler class in the AdapterFactory class, if you like, so that everything is self-contained in AdapterFactory.
Then to use it:
Foo foo = AdapterFactory.createAdapter(new QuietFoo(), Foo.class);
foo.bar();
This approach requires more code than implementing a single adapter, but will be generic enough that it can be used to create auto-adapters for any class and interface pair, not just the QuietFoo and Foo example. Granted, this method uses reflection (the Proxy class uses reflection, as does our InvocationHandler), which can be slower, but recent improvements in the JVM have made reflection much faster than it used to be.
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.