2012-09-03 7 views
5

私のプロジェクトでは、多くのオブジェクトを10個のクラスに分割しています。各オブジェクトはいくつかの操作を実行することができ、事前に登録する必要があります(操作の登録はクラスごとに1回のみ実行されます)。各クラスに対して定義された演算は、public final staticの整数で表されます。私は実行時に操作のIDを動的に割り当てたい(クラスあたりの操作数は現在約20であり、数値は増加する)。ステートメントを切り替えて静的ブロック内の最終静的変数を初期化する

操作が実行され、どの操作が実行されているかを特定する必要があります(私はswitch文を使用します)。

public class Test { 
    final static int foo = 8; 
    final static int bar = 10; 

    public static void main(String[] args) 
    { 
     int x=10; 

     switch(x) 
     { 
     case foo: 
      System.out.println("FOO"); 
      break; 
     case bar: 
      System.out.println("BAR"); 
      break; 
     default: 
      System.out.println("PROBLEM"); 
     } 
    } 
} 

このコードは正常にコンパイルされ、表示さBAR

はここで働いてコードの簡単な例です。

しかし、このわずかに変換されたコードではUnresolved compilation problemcase expressions must be constant expressionsとなります。

public class Test { 
    final static int foo; 
    final static int bar; 

    static 
    { 
     foo=8; 
     bar=10; 
    } 
    public static void main(String[] args) 
    { 
     int x=10; 

     switch(x) 
     { 
     case foo: 
      System.out.println("FOO"); 
      break; 
     case bar: 
      System.out.println("BAR"); 
      break; 
     default: 
      System.out.println("PROBLEM"); 
     } 
    } 
} 

これらのコードは実際に動作し、同じものをコンパイルしてはいけませんか? この問題を解決するまでは何も動的に実行できません。それとも他の方法ですか?我々は2つの列挙型を持っていると私はスイッチを使用して(prefferably 1つのハンドリング機能を持っていると思い

public class Test { 
    enum OperationSet1 { 
    FOO, BAR, THESE, ARE, ALL, DIFFERENT, OPERATIONS 
    } 
    enum OperationSet2 { 
    FOO, BAR, NOW, SOME, OTHER, OPS 
    } 

    public static void main(String[] args) { 
    OperationSet1[] ops = new OperationSet1[10]; 
    for (int i=0; i<ops.length; i++) 
     ops[i] = OperationSet1.values()[(int)(Math.random()*OperationSet1.values().length)]; 

    OperationSet2[] ops2 = new OperationSet2[10]; 
    for (int i=0; i<ops.length; i++) 
     ops[i] = OperationSet2.values()[(int)(Math.random()*OperationSet2.values().length)]; 

    for (OperationSet1 op:ops) 
     handleOperation(op); 
    } 
    for (OperationSet2 op:ops2) 
     handleOperation(op); 
    } 
    public static void handleOperation(Object? op) { 
    switch(op) { 
     /**code to handle**/ 
    } 
    } 
} 

:ため、私はこの問題を解決したいと思います列挙型を使用するためのアイデアへ :

おかげ

EDITステートメント)、これらの2つのenumsにappelleringすべてのケースを処理します。

EDIT2: ここになります。私は10クラス(C1, C2, ..., C10)と約40のこれらのクラスのオブジェクトを持っています。これらのオブジェクトの一部はいわゆる所有者であり、一部は共有されています。各共有オブジェクトには所有者がいます(これは基本的な関係です - java継承とは関係ありません)。

今共有オブジェクトのそれぞれ随時obj変更、およびこのobjニーズが変化してもよい場合、その所有者ownを依頼する(これが唯一の動作である)、次にそれを変更する(そして再び所有者に通知します) 。オブジェクトobjには、C1で定義された、実行可能な事前定義された一連の操作があり、enumによって定義されています。従って、ownはクラスC1のオブジェクト操作のためのハンドリング機能を持たなければならない。ここでは、クラスC2であるオブジェクトobj2があり、異なる操作セットと同じ所有者ownがあります。 objは、C1およびobj2で定義された操作のみを実行する場合、C2で定義された操作のみを実行できます。

取り扱い関数を一般的にどのように書くときれいに書かれますか?列挙型を使うべきか?

+2

直交質問:あなたはint型ではなく列挙型を使用している理由はありますか? –

+0

いいえ理由はありません(私は思う)。私は本当に経験豊富なプログラマーではないので、私は列挙型で実装する方法を実際には見ていません。私はクラスのそれぞれが公開列挙型を保持すると思います(操作あり)?しかし、どのように私は10 enums(各クラスに1つ)以上のスイッチステートメントを作るだろうか? – Nejc

+0

私は、特にデータベースを扱っているときに、良いアイデアとしてenumを使用するとは思わない。 –

答えて

4

コンパイル時に既知の定数は、switch文でのみ使用できます。これは、スイッチコードがチェックされ、静的に構築されているためです。あなたは

static 
{ 
    foo=8; 
    bar=foo; 
} 

を行うことができますが、これらの値は実行時まで知られていないとして、switchステートメントを構築したり、それが正しいことを確認するためのいずれかの方法はありません第2のケースで

+0

私はswitch文の問題を理解しています。しかし、私が投稿した2つのコードの違いは何ですか?彼らはコンパイラによって同じように扱われるべきではありませんか?値は実際には知られています...この 'static'コードはいつ実行されますか? – Nejc

+1

すべてのコードは実行時にのみ実行されるため、コンパイラは実行される内容を認識しません。 –

2

static variables or blocks or methodsは、クラス初期化時(ランタイム)に読み込まれます。

問題は、クラスのロード/初期化のはるか前のコンパイル時です。したがって、フィールドは最終的なもので、初期化されません(コンパイル時に)。

第1のケースでは、foobarの値がコンパイル時にわかります。

0

これにはenumを使用することをおすすめします。このように、IDの取り扱いはもはや必要ではありません。

public class Test { 
    enum Operation { 
    FOO, BAR, THESE, ARE, ALL, DIFFERENT, OPERATIONS 
    } 

    public static void main(String[] args) { 
    Operation[] ops = new Operation[10]; 
    for (int i=0; i<ops.length; i++) 
     ops[i] = Operation.values()[(int)(Math.random()*Operation.values().length)]; 

    for (Operation op:ops) 
     handleOperation(op); 
    } 

    public static void handleOperation(Operation op) { 
    switch(op) { 
    case FOO: 
     System.out.println("FOO"); 
     break; 
    case BAR: 
     System.out.println("BAR"); 
     break; 
    case THESE: 
     System.out.println("THESE"); 
     break; 
    case ARE: 
     System.out.println("ARE"); 
     break; 
    case ALL: 
     System.out.println("ALL"); 
     break; 
    case DIFFERENT: 
     System.out.println("DIFFERENT"); 
     break; 
    case OPERATIONS: 
     System.out.println("OPERATIONS"); 
     break; 
    default: 
     System.out.println("PROBLEM"); 
    } 
    } 
} 
+0

はい、私はこれを1対1の基準で理解しています.1つの列挙型と1つの処理関数(switch文)です。しかし、1からnまでの関係(多くの列挙型と1つの処理switch文)がある場合はどうなりますか? int型の値を1つ渡すだけで、int型が簡単になるようです(もっと多くの列挙型で多くの型の問題に遭遇すると思います...)次に、一般的な型(Object)の引数を受け入れる必要がありますどのような種類のinstanceofベースのswitch文を実行するのですか? – Nejc

+0

私はあなたが望むものを本当に理解していません。この例にいくつかのコードを追加しました。 。 – brimborium

+0

更新された質問を参照してください。 – Nejc

0

または単には、使用している場合は、ELSEIF場合:

private final static int ONE = 1; 
private final static int TWO = 2; 

public static void main(String[] args) { 
int value = 1; 

    if(value==ONE){ 

    } 
    else if(value==TWO){ 

    } 

}