如何隐藏公共方法?

时间:2011-07-19 17:54:16

标签: java annotations scope public-method

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

10 个答案:

答案 0 :(得分:5)

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

class A {
   //Externally visible members
}

class B extends A {
   //Secret public members
}

然后你实例化了B类,但只允许其他人知道A类......

答案 1 :(得分:4)

一旦宣布公开方法,它就成为你班级合同的一部分。您无法隐藏它,因为所有类用户都希望此方法可用。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

如果方法是公开的,则无法隐藏。你真正想要的只是一种限制访问方法的方法。还有其他方法可以达到类似的效果。

如果你的状态机有些东西“只在我的应用程序第一次启动时使用过一次”,那听起来很像那些可能在构造函数中发生的事情。虽然这取决于这些任务的复杂程度,但您可能不希望在施工时这样做。

既然你说状态机是静态的,它还是 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,所以它被视为“第一次访问”并创建实例。如果您确实希望状态机在应用程序启动时执行某些初始化任务,请记住这一点。

因此,如果您不想将状态机类转换为真正的单例...您可以在第一次访问类时使用static initialization block执行一次性任务。这看起来像这样:

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书对State Pattern做了一个很好的,易于理解的处理。如果你还没有,我建议你阅读。

答案 4 :(得分:1)

这样做的惯用方法是使用接口来限制方法的可见性。

例如,假设您有以下课程:

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's answer中倡导的方法类似,但更加灵活:

  • 由于Java不支持多重继承,Mathias的技术无法实现前一段中描述的独立访问控制。
  • 不需要继承关系也可以更灵活地设计类层次结构。
  • 原始类所需的唯一更改是添加implements Method1Interface,这意味着它是非常影响力较小的重构,因为MyClass的现有用户不会必须改变(至少,直到选择更改它们以使用Method1Interface)。

答案 5 :(得分:0)

替代解决方案:您可以使用反射创建private并创建invokeHiddenMethod(String methodName, Object ... args)方法。

答案 6 :(得分:0)

嗯......你想要一个私人方法,但想在外面访问它?

尝试用反射来做这件事。 http://download.oracle.com/javase/tutorial/reflect/index.html

答案 7 :(得分:0)

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

也许你可以将方法公开,但在第一次通话后不做任何事情?

答案 8 :(得分:0)

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

这会使方法或类对类和包中的其他人可见,但会给你一些隐私。您可能需要查看What is the use of package level protection in java?

答案 9 :(得分:0)

我见过很多Java程序员做过这样的事情:

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

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