我的静态机器中有一个方法,该方法仅在我的应用程序首次启动时使用一次。该方法需要公开,但我仍然希望它隐藏。有没有办法使用注释或其他东西可以隐藏项目其余部分的方法?
10 回答
您不能隐藏公共方法(除非您可以将其声明为私有)。但是,您可以放入一个子类,只让对象的用户知道超类的类型,即:
class A {
//Externally visible members
}
class B extends A {
//Secret public members
}
然后你实例化类 B,但只让类型 A 被其他人知道......
一旦你声明了公共方法,它就成为你的类契约的一部分。您无法隐藏它,因为所有班级用户都希望此方法可用。
如果方法是公开的,则不能隐藏。您可能真正要寻找的只是一种限制对调用方法的访问的方法。还有其他方法可以达到类似的效果。
如果您的状态机所做的某些事情“仅在我的应用程序首次启动时使用一次”,那么听起来很像那些可能在构造函数中发生的事情。尽管这取决于这些任务的复杂程度,但您可能不想在构建时这样做。
既然您说您的状态机是静态的,那么它也是Singleton吗?您也许可以使用Singleton Pattern。
public class SimpleStateMachine {
private static SimpleStateMachine instance = new SimpleStateMachine();
private SimpleStateMachine() {
super();
System.out.println("Welcome to the machine"); // prints 1st
}
public static SimpleStateMachine getInstance() {
return instance;
}
public void doUsefulThings() {
System.out.println("Doing useful things"); // prints 3rd
}
}
这是此 Singleton 的客户端的一些代码:
public class MachineCaller {
static SimpleStateMachine machine = SimpleStateMachine.getInstance();
public static void main(String... args) {
System.out.println("Start at the very beginning"); // prints 2nd
machine.doUsefulThings();
}
}
请注意,SimpleStateMachine
直到第一次访问您的类时才会构建实例。因为它是static
在MachineCaller
客户端中声明的,所以算作“首次访问”并创建实例。如果您确实希望您的状态机在应用程序启动时执行其中一些初始化任务,请记住这个花絮。
所以,如果你不想把你的状态机类变成一个真正的单例......你可以使用静态初始化块在第一次访问该类时执行你的一次性任务。看起来像这样:
public class SimpleStateMachine {
static {
System.out.println("First time tasks #1");
System.out.println("First time tasks #2");
}
public SimpleStateMachine() {
super();
System.out.println("Welcome to the machine");
}
public void doUsefulThings() {
System.out.println("Doing useful things");
}
}
当我们讨论它时,既然你提到它是一个状态机...... Head First Design Patterns这本书对状态模式做了一个很好的、易于理解的处理。如果您还没有,我建议您阅读它。
您可以使用包级别而不是公共的。这样它只能由您的应用程序调用。
这样做的惯用方法是使用接口来限制方法的可见性。
例如,假设您有以下课程:
public class MyClass {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
如果您想将项目的某些部分限制为只能看到method1()
,那么您所做的就是在接口中描述它,并让类实现该接口:
public interface Method1Interface {
public void method1();
}
...
public class MyClass implements Method1Interface {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
然后,您可以通过选择将类作为MyClass
引用或作为Method1Interface
引用传递来限制方法的可见性:
public class OtherClass {
public void otherMethod1(MyClass obj) {
// can access both obj.method1() and obj.method2()
}
public void otherMethod2(Method1Interface obj) {
// can only access obj.method1(), obj.method2() is hidden.
}
}
这种方法的一个好处是它也可以很容易地扩展。例如,您现在还想独立控制对method2()
. Method2Interface
您需要做的就是按照与 相同的方式创建一个新的Method1Interface
,并MyClass
实施它。然后,您可以method2()
以与method1()
.
这与@MathiasSchwarz 的回答中提倡的方法类似,但更加灵活:
- 上一段中描述的独立访问控制在 Mathias 的技术中是不可能的,因为 Java 不支持多重继承。
- 不需要继承关系也允许在设计类层次结构时更加灵活。
- 对原始类的唯一更改是添加
implements Method1Interface
,这意味着它是一个影响非常小的重构,因为MyClass
根本不需要更改现有用户(至少,在选择将它们更改为使用之前)Method1Interface
)。
我见过很多 Java 程序员做这样的事情:
public static void main(String args[]) {
new MyClass();
}
所以基本上他们只创建了一个类的对象。如果有一种方法应该只运行一次,我想这种方法可以实现。您的方法将从构造函数内部调用。但是由于我不知道您的应用程序是如何工作的,有什么限制,所以这只是一个想法。
您说您的公共方法仅在应用程序启动时使用一次。
也许您可以将方法公开,但在第一次调用后让它什么都不做?
有一个(非)关键字级别的包级别可见性。而不是公共的、受保护的或私有的,你什么都不用。
这将使该方法或类对包中的类和其他人可见,但会给您一定的隐私。您可能想看看java 中包级保护的用途是什么?.
嗯...您想要一个私有方法,但想在外部访问它?
尝试通过反射来做到这一点。 http://download.oracle.com/javase/tutorial/reflect/index.html
另一种解决方案:您可以制作它private
并使用反射创建一个invokeHiddenMethod(String methodName, Object ... args)
方法。