如何隐藏公共方法?

发布于 2024-11-25 08:51:44 字数 84 浏览 4 评论 0原文

我的静态状态机中有一个方法,仅在我的应用程序首次启动时使用一次。该方法需要公开,但我仍然希望它隐藏。有没有办法使用注释或其他东西来隐藏项目其余部分的方法?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

丿*梦醉红颜 2024-12-02 08:51:44

您不能隐藏公共方法(除非您可以将其声明为私有)。然而,你可以放入一个子类,只让对象的用户知道超类的类型,即:

class A {
   //Externally visible members
}

class B extends A {
   //Secret public members
}

然后你实例化类 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:

class A {
   //Externally visible members
}

class B extends A {
   //Secret public members
}

Then you instantiate the class B, but only let the type A be known to others...

紫瑟鸿黎 2024-12-02 08:51:44

一旦你声明了公共方法,它就成为你的类契约的一部分。您无法隐藏它,因为所有类用户都希望此方法可用。

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.

北方的韩爷 2024-12-02 08:51:44

您可以使用包级别而不是公共级别。这样它只能由您的应用程序调用。

You could use package level instead of public. That way it can only be called by your application.

遇见了你 2024-12-02 08:51:44

如果方法是公共的,则无法隐藏它。您真正需要的可能只是一种限制调用方法的方法。还有其他方法可以达到类似的效果。

如果您的状态机执行的某些操作“仅在我的应用程序首次启动时使用一次”,那么听起来很像这些操作可能在构造函数中发生。尽管这取决于这些任务的复杂程度,但您可能不想在构建时这样做。

既然你说你的状态机是静态的,那么它也是一个单例吗?您也许可以使用单例模式

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 实例。因为它在 MachineCaller 客户端中声明为 static,所以算作“首次访问”并创建实例。如果您确实希望状态机在应用程序启动时执行其中一些初始化任务,请记住这一点。

因此,如果您不想将状态机类变成真正的单例...您可以使用 静态初始化块 在第一次访问类时执行一次性任务。看起来像这样:

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 一书对 状态模式。如果您还没有阅读过,我建议您阅读一下。

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.

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

Here's some code for a client of this 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();
    }
}

Note that the SimpleStateMachine instance isn't built until the first time your class is accessed. Because it's declared as static in the MachineCaller 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:

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");
    }
}

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.

何时共饮酒 2024-12-02 08:51:44

执行此操作的惯用方法是使用接口来限制方法的可见性。

例如,假设您有以下类:

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() 的访问。您所需要做的就是按照与 Method1Interface 相同的方式创建一个新的 Method2Interface,并让 MyClass 实现它。然后,您可以按照与 method1() 完全相同的方式控制对 method2() 的访问。

提倡的方法类似,但更加灵活:

  • 这与 @MathiasSchwarz 的回答中 由于 Java 不支持多重继承,Mathias 的技术不可能实现前面的段落。
  • 不需要继承关系还可以在设计类层次结构时提供更大的灵活性。
  • 对原始类所需的唯一更改是添加 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:

public class MyClass {
    public void method1() {
        // ...
    }
    public void method2() {
        // ...
    }
}

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:

public interface Method1Interface {
    public void method1();
}

...

public class MyClass implements Method1Interface {
    public void method1() {
        // ...
    }
    public void method2() {
        // ...
    }
}

Then, you can limit the visibility of the methods by choosing to pass the class around either as a MyClass reference, or as a Method1Interface reference:

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

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 new Method2Interface along the same lines as Method1Interface, and have MyClass implement it. Then, you can control access to method2() in exactly the same manner as method1().

This is a similar approach to that advocated in @MathiasSchwarz's answer, but is much more flexible:

  • The independent access control described in the preceding paragraph isn't possible with Mathias' technique, due to Java not supporting multiple inheritance.
  • Not requiring an inheritance relationship also allows more flexibility in designing the class hierarchy.
  • The only change required to the original class is to add implements Method1Interface, which means that it is a very low-impact refactor since existing users of MyClass don't have to be changed at all (at least, until the choice is made to change them to use Method1Interface).
情痴 2024-12-02 08:51:44

另一种解决方案:您可以将其设为私有并使用反射创建一个 invokeHiddenMethod(String methodName, Object ... args) 方法。

An alternative solution: You can make it private and create a invokeHiddenMethod(String methodName, Object ... args) method using reflection.

笑脸一如从前 2024-12-02 08:51:44

您说您的公共方法仅在应用程序启动时使用一次。

也许您可以将该方法保留为公共,但在第一次调用后使其不执行任何操作?

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?

╭ゆ眷念 2024-12-02 08:51:44

有(非)关键字级别包级别可见性。你什么都不用,而不是公共的、受保护的或私有的。

这将使方法或类对该类和包中的其他人可见,但会给您一定程度的隐私。您可能想看看 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?.

七月上 2024-12-02 08:51:44

嗯...您想要一个私有方法,但想在外部访问它?

尝试通过反思来做到这一点。
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

时光无声 2024-12-02 08:51:44

我见过许多 Java 程序员这样做:

public static void main(String args[]) {
      new MyClass();
}

所以基本上他们只创建类的一个对象。如果有一个方法应该只运行一次,我想这种方法可以实现这一点。您的方法将从构造函数内部调用。但由于我不知道你的应用程序是如何工作的,有什么限制,所以这只是一个想法。

I have seen many Java programmers do something like this:

public static void main(String args[]) {
      new MyClass();
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文