2015-03-30 38 views
3

比方說,我有一個ParkingMeter類和一個ParkingSlip類。 ParkingSlips只能在ParkingMeter課程內創建,但ParkingSlips應該可以通過名爲Car的外部課程訪問(因此您可以檢查每輛車是否支付了停車費用)。如何確保僅在特定類中實例化類?

是否有辦法確保ParkingSlips只能從ParkingMeter內部創建,但仍可供其他類訪問?

+1

使用ParkingSlips的私有構造函數。 http://stackoverflow.com/questions/17342815/what-is-the-use-of-private-constructor-in-java – chiaboy 2015-03-30 23:32:32

+2

使ParkingSlips成爲ParkingMeter的私人內部類。然後寫一個getter方法來獲得ParkingSlips(而不是setter)。有車在ParkingMeter中呼叫吸氣器 – 2015-03-30 23:32:53

+2

當然可以。您可以看到Inner Class:https://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html。您可以將ParkingSlip作爲ParkingMeter的內部類。汽車可以通過getter獲得ParkingSlip對象。 – MageXellos 2015-03-30 23:33:21

回答

2

如果您不想讓ParkingSlip爲內部類,請將這兩個類放在同一個包中,並使ParkingSlip的構造函數包爲私有。它不會阻止同一包裹中的其他班級製作停車卡片,但它會阻止其他包裹中的壞人。

package parking; 

public class ParkingSlip { 
    ParkingSlip() { 
    } 
} 

public class ParkingMeter { 
    public ParkingSlip getSlip() { 
     return new ParkingSlip(); 
    } 
} 
2

最安全的方法是使ParkingSlip公開內部靜態類ParkingMeter並給它一個私人構造函數。

public class ParkingMeter { 
    public static class ParkingSlip { 
     private ParkingSlip() { 
     } 
    } 
} 

一個不太安全的,但更可用,方法是給默認(又名「包」)能見度構造和在同一個包有ParkingMeter,但來自同一個包中的任何其它類 - 即使從不同的項目 - 將有權訪問構造函數。

請注意,無論你走到哪裏,反射都可以繞過它。

1

其實有一種方法來檢查誰調用構造函數或方法:
檢查當前的堆棧跟蹤
不,我會推薦它,但是,嘿,它的工作原理:

public ParkingSlip() { 

    // get the current stack trace 
    // element 0: java.lang.Thread.getStackTrace 
    // element 1: this constructor 
    // element 2: the class/method calling this constructor 
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 

    // verify that it was indeed the ParkingMeter who invoked the constructor 
    if (!ParkingMeter.class.getName().equals(stackTrace[2].getClassName())) { 
     throw new IllegalAccessError("Restricted access, only ParkingMeter is allowed to create instances"); 
    } 
} 

一個清潔的解決方案,這resticts在編譯時(在運行時只有以上檢查溶液)構造函數訪問是

  • 地方ParkingMeterParkingSlip(只有那些二)在專用包
  • 離開這兩個類public
  • 使構造函數(一個或多個)的F或ParkingSlip「友好」(均未private,也不protected,也不public

這確保了ParkingSlip構造只能由類在同一包訪問,並作爲ParkingMeter是唯一的其他類在該包,你有你想要的。

public class ParkingSlip { 

    // 'friendly' constructor 
    ParkingSlip() { 
    } 
}