2012-08-08 14 views
0

如何避免從外界創建B類對象,並只允許通過A類?如何避免從外界創建B類對象,並只允許通過A類

我有2類

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(); 

    } 
} 
+0

從public void B移除public !! – perilbrain 2012-08-08 07:16:16

+0

我們可以檢查哪個類試圖創建B類的默認構造函數中的類B的對象嗎? – 2012-08-08 07:22:18

+0

AFAIK,它不可能找到正在嘗試創建另一個類的實例的類,因爲對象創建是在JVM的控制之下。 – sundar 2012-08-08 07:25:01

回答

0

這裏是溶液,其工作..

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類可以是任何包。

using public static boolean isFromAClass = false;領域,它實現了。

只有我需要改變,而不是OD廣義例外,它應該是定製的異常爲OutSideAClassBClassInstanceShouldNotBeCreated

+0

上面的解決方案是否存在任何循環漏洞? – 2012-08-08 08:08:55

0

一個簡單的解決方案是將兩個AB在示例包。然後,讓類B公開,但其構造package訪問或protected

A是:

package my; 
public class A {} 

和類B是:

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

如果確實不需要類B外這個包,你甚至可以讓這個類本身成爲一個訪問包。

0

將B類放入與A相同的包中,並使其構造函數包受保護。只有來自同一個包的類才能夠調用它。

+0

但是如果客戶端在同一個包中,那麼它可以創建類B的對象。 – 2012-08-08 07:16:47

+1

如果客戶端在同一個包中,那麼它不是外部世界了。如果您真的想限制對A的訪問,請將其設爲A的內部靜態類,並將其構造函數設爲私有。 – 2012-08-08 07:19:02

0

您可以使B具有私有構造函數的內部(靜態)類A

class B { 

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

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

} 
1

儘量讓B類作爲一個內部類A級,並指定B類的範圍,因爲私人

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

+0

內部類是選項之一,但對我的實現來說不可行。我需要這兩個不同的課程。 – 2012-08-08 07:18:02

0

可以使用私有靜態嵌套類:

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 
    } 
2

我能想到的一個解決方案是使用內部靜態類A:KeyToB w ith是一個私人構造函數,B需要這個構造函數來實例化。因此,只有A可以instanciate B,它可以在不同的文件中。

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() {  
    } 
} 
+2

建議的解決方案確實有效。但是,我想知道用例是什麼。一般來說,當一個人問自己這樣一個棘手的問題時,現在是時候回到主要用例,並詢問這個問題的答案是否是好答案... – 2012-08-08 08:07:14

0
public class A { 

    private class B{ 

     private B(){ 

     }  
    } 

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

} 
1

使用Inner Class概念。所述Outer Class(即類裏面)的

Private構件所有Inner Class(即封閉類)內它訪問,並且反之亦然

因此,讓Class A外部類Class B作爲private內部類

public class A { 

     B obj; 

     public A() { 

     obj = new B(); 

     } 


     private class B { 

      public void methodB() {    

      } 

     } 
    } 
相關問題