Re: How to let the methods of a class only can be invoked by a special
    package(the class not in the package)?
 
Thomas Schodt wrote:
Jebel.Star@gmail.com wrote:
There is a class A in package xx.zz.gg , and A has a static method
A.getInstance(). There are 3 classes B, C, D in package xx.zz
How can I make the A.getInstance() only can be invoked by the B, C and D
class A {
  private A() {};
  private static final Set allowed = new HashSet() {{
    add("xx.zz.B");
    add("xx.zz.C");
    add("xx.zz.D");
  }};
  static A a = null;
  static A getInstance() {
    Class[] ca = new SecurityManager() {
        protected Class[] getClassContext() {
            return super.getClassContext();
        }
    }.getClassContext();
    // ca[0] is the anonymous security manager
    // ca[1] is this class ("A")
    // ca[2] is the calling class
    if (!allowed.contains(ca[2].getName())) {
      throw new InstantiationError("Not allowed from "+ca[2]);
    }
    if (a==null) { a = new A(); }
    return a;
  }
}
That's a great pattern.  Take it a step further and store a
Map <String, Class <? extends Allowed>>
or a Map <AllowedEnum, Class <? extends Allowed>>
where 'Allowed' is a supertype for the classes that are allowed.  The 'String' 
or 'AllowedEnum' enum identify the particular implementing class for each case 
you want to permit.
For that matter, you could craft an 'AllowedEnum' where each enum instance's 
behavior does what you want - that could well be your optimal solution in that 
it gives you compile-time safety on the behaviors, not merely run-time checks. 
  From a maintenance standpoint, such an enum collects verification of an 
action's legality and its activity into a single class, binding them at 
compile time, making life easier.
The downside to the enum implementation is that you have to recompile the 
world to extend the behaviors.  If runtime configurability is what you need, 
then you need a runtime technique such as the ServiceProvider pattern.
-- 
Lew