如何隐藏公共方法?
我的静态状态机中有一个方法,仅在我的应用程序首次启动时使用一次。该方法需要公开,但我仍然希望它隐藏。有没有办法使用注释或其他东西来隐藏项目其余部分的方法?
I have a method in my static state machine that is only used once when my application is first fired up. The method needs to be public, but I still want it hidden. Is there a way to use an annotation or something that will hide the method from the rest of the project?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
您不能隐藏公共方法(除非您可以将其声明为私有)。然而,你可以放入一个子类,只让对象的用户知道超类的类型,即:
然后你实例化类 B,但只让类型 A 被其他人知道......
You cannot make a public method hidden (unless you can declare it private). You can however put in a subclass and only let the users of the object know the type of the superclass, that is:
Then you instantiate the class B, but only let the type A be known to others...
一旦你声明了公共方法,它就成为你的类契约的一部分。您无法隐藏它,因为所有类用户都希望此方法可用。
Once you declare public method it becomes part of your class's contract. You can't hide it because all class users will expect this method to be available.
您可以使用包级别而不是公共级别。这样它只能由您的应用程序调用。
You could use package level instead of public. That way it can only be called by your application.
如果方法是公共的,则无法隐藏它。您真正需要的可能只是一种限制调用方法的方法。还有其他方法可以达到类似的效果。
如果您的状态机执行的某些操作“仅在我的应用程序首次启动时使用一次”,那么听起来很像这些操作可能在构造函数中发生。尽管这取决于这些任务的复杂程度,但您可能不想在构建时这样做。
既然你说你的状态机是静态的,那么它也是一个单例吗?您也许可以使用单例模式。
以下是此 Singleton 的客户端的一些代码:
请注意,直到第一次访问您的类时才会构建
SimpleStateMachine
实例。因为它在MachineCaller
客户端中声明为static
,所以算作“首次访问”并创建实例。如果您确实希望状态机在应用程序启动时执行其中一些初始化任务,请记住这一点。因此,如果您不想将状态机类变成真正的单例...您可以使用 静态初始化块 在第一次访问类时执行一次性任务。看起来像这样:
当我们这样做时,既然您提到它是一个状态机... Head First Design Patterns 一书对 状态模式。如果您还没有阅读过,我建议您阅读一下。
If a method is public, it can't be hidden. What you may really be looking for is just a way to restrict access to calling a method. There are other ways to achieve a similar effect.
If there are some things that your state machine does that are "only used once when my application is first fired up" it sounds a lot like those are things that could happen in the constructor. Although it depends on how complex those tasks are, you may not want to do that at construction time.
Since you said your state machine is static, is it also a Singleton? You could maybe use the Singleton Pattern.
Here's some code for a client of this Singleton:
Note that the
SimpleStateMachine
instance isn't built until the first time your class is accessed. Because it's declared asstatic
in theMachineCaller
client, that counts as a "first access" and creates the instance. Keep this tidbit in mind if you definitely want your state machine to perform some of those initialization tasks at the time your application starts up.So, if you don't want to turn your state machine class into a true singleton... you can use a static initialization block do your one-time tasks the first time the class is accessed. That would look something like this:
While we're at it, since you mentioned that it's a state machine... the Head First Design Patterns book does a nice, easily understandable treatment of the State Pattern. I recommend reading it if you haven't already.
执行此操作的惯用方法是使用接口来限制方法的可见性。
例如,假设您有以下类:
如果您想限制项目的某些部分只能看到
method1()
,那么您要做的就是在接口中描述它,并让该类实现该接口:然后,您可以通过选择将类作为
MyClass
引用或作为Method1Interface
引用传递来限制方法的可见性:这样做的好处方法是它也可以很容易地扩展。例如,您现在还想独立控制对
method2()
的访问。您所需要做的就是按照与Method1Interface
相同的方式创建一个新的Method2Interface
,并让MyClass
实现它。然后,您可以按照与method1()
完全相同的方式控制对method2()
的访问。提倡的方法类似,但更加灵活:
implements Method1Interface
,这意味着自从MyClass
的现有用户以来,它是一个非常低影响的重构> 根本不必更改(至少在选择将它们更改为使用Method1Interface
之前)。The idiomatic approach to doing this is to use interfaces to limit the visibility of your methods.
For example, say you have the following class:
If you want to limit some parts of the project to only see
method1()
, then what you do is describe it in an interface, and have the class implement that interface:Then, you can limit the visibility of the methods by choosing to pass the class around either as a
MyClass
reference, or as aMethod1Interface
reference:A bonus of this approach is that it can also be easily extended. Say, for example, you now also want to independently control access to
method2()
. All you need do is create a newMethod2Interface
along the same lines asMethod1Interface
, and haveMyClass
implement it. Then, you can control access tomethod2()
in exactly the same manner asmethod1()
.This is a similar approach to that advocated in @MathiasSchwarz's answer, but is much more flexible:
implements Method1Interface
, which means that it is a very low-impact refactor since existing users ofMyClass
don't have to be changed at all (at least, until the choice is made to change them to useMethod1Interface
).另一种解决方案:您可以将其设为私有并使用反射创建一个
invokeHiddenMethod(String methodName, Object ... args)
方法。An alternative solution: You can make it
private
and create ainvokeHiddenMethod(String methodName, Object ... args)
method using reflection.您说您的公共方法仅在应用程序启动时使用一次。
也许您可以将该方法保留为公共,但在第一次调用后使其不执行任何操作?
You said that your public method is used only once when the application is started up.
Perhaps you could leave the method public, but make it do nothing after the first call?
有(非)关键字级别包级别可见性。你什么都不用,而不是公共的、受保护的或私有的。
这将使方法或类对该类和包中的其他人可见,但会给您一定程度的隐私。您可能想看看 package 的用途是什么java中的级别保护?。
There is a (non-)keyword level package level visibility. Instead of public, protected, or private, you use nothing.
This would make the method or class visible to the class and others in the package, but would give you a certain modicum of privacy. You may want to look at What is the use of package level protection in java?.
嗯...您想要一个私有方法,但想在外部访问它?
尝试通过反思来做到这一点。
http://download.oracle.com/javase/tutorial/reflect/index.html
Hmm... You want a private method, but want to access it outside?
Try do this with reflection.
http://download.oracle.com/javase/tutorial/reflect/index.html
我见过许多 Java 程序员这样做:
所以基本上他们只创建类的一个对象。如果有一个方法应该只运行一次,我想这种方法可以实现这一点。您的方法将从构造函数内部调用。但由于我不知道你的应用程序是如何工作的,有什么限制,所以这只是一个想法。
I have seen many Java programmers do something like this:
So basically they create just one object of the class. If there is a method which should run only once, I guess this approach can achieve that. Your method will be called from inside the constructor. But since I don't know how your app works, what are the constraints, so it is just a thought.