假设我有一个ParkingMeter
课程和一个ParkingSlip
课程。 ParkingSlips只能在ParkingMeter
班级内创建,但ParkingSlips
应该可以通过名为Car
的外部班级访问(这样您就可以检查每辆车是否已支付停车费用)。
有没有办法确保只能在ParkingMeter中创建ParkingSlips
但仍可供其他类访问?
答案 0 :(得分:2)
如果您不想将ParkingSlip
作为内部类,请将这两个类放在同一个包中,并使ParkingSlip
的构造函数包为private。它不会阻止同一个包中的其他类创建停车单,但它会阻止其他包中的恶人。
package parking;
public class ParkingSlip {
ParkingSlip() {
}
}
public class ParkingMeter {
public ParkingSlip getSlip() {
return new ParkingSlip();
}
}
答案 1 :(得分:2)
最安全的方法是使ParkingSlip公共内部静态类ParkingLter并为其提供私有构造函数。
public class ParkingMeter {
public static class ParkingSlip {
private ParkingSlip() {
}
}
}
一种不太安全但更有用的方法是给构造函数提供默认(也称为“包”)的可见性,并将ParkingMeter放在同一个包中,但来自同一个包的任何其他类 - 甚至来自不同的项目 - 都将有权访问构造函数。
请注意,无论你走哪条路,反思都可以绕过它。
答案 2 :(得分: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");
}
}
一个更干净的解决方案,它在编译时重新构造构造函数访问(上面的解决方案仅在运行时检查)是
ParkingMeter
和ParkingSlip
(仅限这两个)放在专用包中public
ParkingSlip
友好'的构造函数。 (既不是private
,也不是protected
,也不是public
)这确保了ParkingSlip
构造函数只能由同一个包中的类访问,并且ParkingMeter
是该包中唯一的其他类,您已经得到了所需的内容。
public class ParkingSlip {
// 'friendly' constructor
ParkingSlip() {
}
}