0

How to avoid B Class object creation from outside world, and allow through only A Class ?

I have 2 classes

public class A {
    B obj = null;
    public A() {
        obj = new B();
    }        
    public void methodA () {
        obj.methodB();
    }        
    // other methods
}

public class B {
    public void methodB () {
        // some logic            
    }
    //other methods
}

public class Client {
    public static void main (String s[]) {
        // Valid Call            
        A obj = new A();
        obj.methodA();  // Since methodB is called internally

        // Invalid Call , How to restrict this B object creation here ?
        B objB = new B();
        objB.methodB();

    }
}
4

9 回答 9

2

One solution I can think of is to use a inner static class of A: KeyToB with a private constructor, that is needed by B to be instanciated. Therefore, there is only A that can instanciate B, which can be in a different file.

public class A {
    B obj = null;
    public A() {
        obj = new B(instance);
    }
    public void methodA() {
        obj.methodB();
    }
    // other methods ..

    //The key to have the right to instanciate B, only visible in A
    private static KeyToB instance = new KeyToB();

    public static class KeyToB{
        private KeyToB() {
        }
    }
}

public class B {
    //The constructor is package visible, it need a non null instance of KeyToB . If someone use new B(null), it will get a RuntimeException
    B(KeyToB instance) {
        if (instance == null){
            throw new IllegalArgumentException("B can only be instanciated by A");
        }
    }
    public void methodB() {     
    }   
}
于 2012-08-08T07:21:26.957 回答
1

Try to make the class B as an inner class of class A and specify the scope of class B as private

class A {
    B b = null;
    public A() {
    b = new B();    
    }
     public void testA() {
       return b.methodB();
     }

    private class B {

         public void methodB () {             
                   // some logic                     
         }  

    }
}

http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html

于 2012-08-08T07:16:45.217 回答
1

Use the concept of Inner Class.

Private members of the Outer Class (ie Enclosing Class) is accessible to all the Inner Class (ie Enclosed Class) within it, and vice-versa

So let Class A be the Outer Class, and Class B as the private Inner Class

public  class A {

        B obj;

        public A() {

        obj = new B(); 

        }


        private class B {

             public void methodB () {             

             }  

        }
    }
于 2012-08-08T07:46:24.763 回答
0

A simple solution is to put both A and B in the sample package. Then make class B public but its constructor package access or protected:

Class A would be:

package my;
public class A {}

and class B would be:

package my;
public class B {
   B() {}
}

If class B is actually not needed outside the package, you can also even make the class itself a package access one.

于 2012-08-08T07:14:29.080 回答
0

Put the B class in the same package as A, and make its constructor package-protected. Only the classes from the same package will be able to invoke it.

于 2012-08-08T07:15:22.413 回答
0

You can make B a inner (static) class of A with private constructor.

class B {

    public A createA() {
        A a = new A();
        return a;
    }

    public static class A {
        private A() {}
    }

}
于 2012-08-08T07:16:34.320 回答
0

You can use private static nested class:

    public class A {
        private static class B {
            public void methodB () {
                // some logic            
            }
            //other methods
        }

        B obj = null;

        public A() {
            obj = new B();
        }        
        public void methodA () {
            obj.methodB();
         }        
         // other methods
   }
于 2012-08-08T07:17:33.213 回答
0
public class A {

    private class B{

        private B(){

        }       
    }

    public B createB(){
        return new B();
    }

}
于 2012-08-08T07:21:42.917 回答
0

Here is solution, its working ..

public class A {

    public static boolean isFromAClass = false;
    B obj = null;

    public A() {
        try {
            isFromAClass = true;
            obj = new B();
            isFromAClass = false;
        } catch (Exception e) {
        }
    }

    public void methodA() {
        System.out.println("methodA");
        obj.methodB();
    }
    // other methods
}

public class B {

    public B () throws Exception {
        if(!A.isFromAClass) {
            throw new Exception();
        }
    }
    public void methodB() {
        System.out.println("methodB");
        // some logic
    }
    //other methods
}

public class Client {

    public static void main(String s[]) throws Exception {
        // Valid Call
        A obj = new A();
        obj.methodA();  // Since methodB is called internally

        // Invalid Call , How to restrict this B object creation here ?
        B objB = new B(); // this line throws Exception
        objB.methodB();

    }
}

A, B, Client class may be in any package.

using public static boolean isFromAClass = false; field, it is achieved.

Only I need to change, instead od generalized Exception, it should be customized Exception as OutSideAClassBClassInstanceShouldNotBeCreated

于 2012-08-08T07:41:22.547 回答