3

静的ステートマシンに、アプリケーションが最初に起動されたときに1回だけ使用されるメソッドがあります。メソッドは公開する必要がありますが、それでも非表示にします。プロジェクトの残りの部分からメソッドを隠すアノテーションまたは何かを使用する方法はありますか?

4

10 に答える 10

6

パブリックメソッドを非表示にすることはできません(プライベートとして宣言できない場合)。ただし、サブクラスを配置して、オブジェクトのユーザーにのみスーパークラスのタイプを知らせることができます。つまり、次のようになります。

class A {
   //Externally visible members
}

class B extends A {
   //Secret public members
}

次に、クラスBをインスタンス化しますが、タイプAだけを他の人に知らせます...

于 2011-07-19T17:58:09.993 に答える
4

public methodを宣言すると、それはクラスのコントラクトの一部になります。すべてのクラスユーザーがこのメソッドが使用可能であることを期待するため、非表示にすることはできません。

于 2011-07-19T17:57:29.953 に答える
1

publicの代わりにパッケージレベルを使用できます。そうすれば、アプリケーションからのみ呼び出すことができます。

于 2011-07-19T17:58:30.793 に答える
1

メソッドがパブリックの場合、非表示にすることはできません。あなたが本当に探しているのは、メソッドの呼び出しへのアクセスを制限する方法にすぎません。同様の効果を達成する他の方法があります。

ステートマシンが実行する「アプリケーションが最初に起動されたときに1回だけ使用される」ことがある場合、それらはコンストラクターで発生する可能性があることとよく似ています。これらのタスクがどれほど複雑かにもよりますが、構築時にそれを実行したくない場合があります。

ステートマシンは静的であるとおっしゃっていましたが、シングルトンでもありますか?シングルトンパターンを使用できます。

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

このシングルトンのクライアントのコードは次のとおりです。

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クラスに最初にアクセスするまで、インスタンスはビルドされないことに注意してください。クライアントで宣言されているため、これstaticMachineCaller「最初のアクセス」としてカウントされ、インスタンスが作成されます。アプリケーションの起動時にステートマシンでこれらの初期化タスクの一部を確実に実行する場合は、この点に注意してください。

したがって、ステートマシンクラスを真のシングルトンに変えたくない場合は、静的初期化ブロックを使用して、クラスに初めてアクセスしたときに1回限りのタスクを実行できます。これは次のようになります。

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の本は、ステートパターンの素晴らしくて簡単に理解できる扱いをします。まだ読んでいない場合は、読むことをお勧めします。

于 2011-07-19T18:18:30.377 に答える
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の回答で提唱されているアプローチと似ていますが、はるかに柔軟です。

  • 前の段落で説明した独立したアクセス制御は、Javaが多重継承をサポートしていないため、Mathiasの手法では不可能です。
  • 継承関係を必要としないことで、クラス階層をより柔軟に設計することもできます。
  • 元のクラスに必要な唯一の変更は、を追加することです。これは、の既存のユーザーをまったく変更する必要がないため(少なくとも、使用するように変更することを選択するまで)、影響が非常に少ないリファクタリングimplements Method1Interfaceであることを意味します。 )。MyClassMethod1Interface
于 2016-04-20T00:10:06.423 に答える
0

別の解決策:それを作成し、リフレクションを使用しprivateてメソッドを作成できます。invokeHiddenMethod(String methodName, Object ... args)

于 2011-07-19T17:56:44.950 に答える
0

うーん...プライベートメソッドが必要ですが、外部からアクセスしたいですか?

リフレクションでこれを試してください。 http://download.oracle.com/javase/tutorial/reflect/index.html

于 2011-07-19T17:57:52.297 に答える
0

パブリックメソッドは、アプリケーションの起動時に1回だけ使用されるとおっしゃいました。

おそらく、メソッドを公開したままにして、最初の呼び出しの後で何もしないようにすることはできますか?

于 2011-07-19T17:59:29.013 に答える
0

(非)キーワードレベルのパッケージレベルの可視性があります。パブリック、保護、またはプライベートの代わりに、何も使用しません。

これにより、メソッドまたはクラスがパッケージ内のクラスや他のユーザーに表示されますが、ある程度のプライバシーが確保されます。Javaでのパッケージレベルの保護の使用とは何ですか?

于 2011-07-19T18:00:05.940 に答える
0

私は多くのJavaプログラマーがこのようなことをするのを見てきました:

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

つまり、基本的には、クラスのオブジェクトを1つだけ作成します。一度だけ実行する必要があるメソッドがある場合、このアプローチでそれを達成できると思います。メソッドはコンストラクター内から呼び出されます。しかし、あなたのアプリがどのように機能するのかわからないので、制約は何ですか、それは単なる考えです。

于 2011-07-19T18:16:20.947 に答える