2012-09-03 16 views
5

में अंतिम स्थैतिक चर प्रारंभ करना मेरी प्रोजेक्ट के लिए, मेरे पास कई ऑब्जेक्ट्स 10 कक्षाओं में विभाजित हैं। प्रत्येक वस्तुएं कुछ परिचालन कर सकती हैं, जिन्हें पहले से पंजीकृत किया जाना है (संचालन का पंजीकरण प्रति कक्षा केवल एक बार किया जाता है)। प्रत्येक वर्ग के लिए परिभाषित ऑपरेशंस को public final static पूर्णांक के रूप में दर्शाया जाता है। मैं रनटाइम पर संचालन की आईडी गतिशील रूप से असाइन करना चाहता हूं (प्रति वर्ग संचालन की संख्या वर्तमान में लगभग 20 है और संख्या में वृद्धि होगी)।स्विच स्टेटमेंट और स्टेटिक ब्लॉक

समस्या उत्पन्न होती है, जब कोई ऑपरेशन किया जाता है और मुझे यह पता लगाना पड़ता है कि कौन सा ऑपरेशन किया जा रहा है (मैं एक स्विच स्टेटमेंट का उपयोग करता हूं)।

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 problem उत्पन्न करता है।

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

क्या ये कोड वास्तव में काम नहीं करते और संकलित नहीं करते हैं? मैं इस समस्या को हल करने तक गतिशील रूप से कुछ भी करने में सक्षम नहीं हूं? या कोई और तरीका है?

धन्यवाद

संपादित करें:

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

हम दो enums है और मैं स्विच के साथ (prefferably एक हैंडलिंग समारोह करना चाहते हैं: enums उपयोग करने के विचारों मैं इस समस्या का समाधान चाहते हैं के कारण कथन), जो इन दो enums में सभी मामलों को लागू करने के लिए संभाल लेंगे।

EDIT2: तो यहां जाता है। मेरे पास 10 वर्ग (C1, C2, ..., C10) और इन कक्षाओं के लगभग 40 ऑब्जेक्ट हैं। इनमें से कुछ वस्तुएं तथाकथित मालिक हैं और कुछ साझा की जाती हैं। प्रत्येक साझा ऑब्जेक्ट में एक स्वामी होता है (यह मूल संबंध है - इसमें जावा विरासत के साथ कुछ भी नहीं है)।

अब साझा वस्तुओं obj समय-समय पर परिवर्तन, और इस obj जरूरतों में से प्रत्येक के अपने मालिक own पूछने के लिए अगर यह बदल सकते हैं (यह केवल संचालन में से एक है) और फिर यह परिवर्तन (और फिर मालिक को सूचित करता है) । ऑब्जेक्ट obj में C1 में enum द्वारा परिभाषित किए गए संचालन का पूर्वनिर्धारित सेट भी है। इसलिए own वर्ग C1 के ऑब्जेक्ट ऑपरेशंस के लिए एक हैंडलिंग फ़ंक्शन होना चाहिए। अब हमारे पास ऑब्जेक्ट obj2 है जो C2 वर्ग है, इसमें संचालन का एक अलग सेट है और एक ही मालिक own है। objC1 और obj2 में परिभाषित केवल संचालन निष्पादित कर सकता है केवल C2 में परिभाषित संचालन कर सकता है।

हैंडलिंग फ़ंक्शन को सामान्यीकृत करने के लिए कैसे इसे अच्छी तरह से लिखा जाएगा? क्या मुझे भी enums का उपयोग करना चाहिए?

+2

ओर्थोगोनल प्रश्न: वहाँ एक कारण है कि आप ints और नहीं एक enum का उपयोग कर रहे है? –

+0

कोई कारण नहीं है (मुझे लगता है)। मैं वास्तव में एक बहुत अनुभवी प्रोग्रामर नहीं हूं, इसलिए मैं वास्तव में नहीं देखता हूं, मैं इसे enums के साथ कैसे लागू करूंगा। मुझे लगता है कि प्रत्येक वर्ग में एक सार्वजनिक enum (संचालन के साथ) होगा? लेकिन मैं 10 enums (प्रत्येक वर्ग के लिए एक) पर एक स्विच स्टेटमेंट कैसे बनाऊंगा? – Nejc

+0

मैं अच्छे विचार के रूप में enums का उपयोग करने के बारे में नहीं सोचता, खासकर जब आप डेटाबेस से निपट रहे हैं। –

उत्तर

4

आप केवल स्विच स्टेटमेंट में संकलन समय पर ज्ञात स्थिरांक का उपयोग कर सकते हैं। ऐसा इसलिए है क्योंकि स्विच कोड की जांच की जाती है और स्थिर रूप से बनाया जाता है।

दूसरे मामले में आप

static 
{ 
    foo=8; 
    bar=foo; 
} 

कर सकता है लेकिन जैसा कि इन मूल्यों क्रम जब तक नहीं जाना जाता है, वहाँ कोई रास्ता नहीं है या तो स्विच बयान का निर्माण या जाँच यह सही है करने के लिए किया जाएगा।

+0

मैं स्विच स्टेटमेंट के साथ समस्या को समझता हूं। लेकिन मुझे नहीं पता कि मैंने पोस्ट किए गए दो कोडों के बीच क्या अंतर है? क्या उन्हें कंपाइलर द्वारा उसी तरह से इलाज नहीं किया जाना चाहिए? मान वास्तव में ज्ञात हैं ... यह 'स्थिर' कोड कब निष्पादित किया जाता है? – Nejc

+1

किसी भी कोड को केवल रनटाइम पर निष्पादित किया जाता है, जैसे कि कंपाइलर को यह नहीं पता कि इसे किस प्रकार निष्पादित किया जाएगा। –

2

static variables or blocks or methods क्लास प्रारंभिकरण (रनटाइम) के समय लोड हो जाते हैं।

आपकी समस्या संकलन समय पर है जो कक्षा के लोडिंग/इंटिलाइजिंग से बहुत दूर है। तो फ़ील्ड अंतिम हैं और इन्हें इंटिलाइज्ड नहीं किया जाता है (संकलन समय पर)।

1 मामले में, foo और bar के मान संकलन समय पर ज्ञात हैं।

0

मैं इसके लिए enums का उपयोग करने की सलाह देते हैं। इस तरह आईडी हैंडलिंग अब और अधिक नहीं है।

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 आधार पर समझता हूं ... तो एक enum और एक हैंडलिंग फ़ंक्शन (स्विच स्टेटमेंट)। लेकिन क्या मामला है जब 1 से 'एन' संबंध (कई enums और एक हैंडलिंग स्विच स्टेटमेंट) है? ऐसा लगता है कि इनट्स आसान हैं, क्योंकि आप केवल एक प्रकार के int int को पास करते हैं (मुझे लगता है कि आपको कई प्रकार की समस्याएं मिलती हैं ... फिर आपको कुछ सामान्य प्रकार (ऑब्जेक्ट) का तर्क स्वीकार करना होगा और फिर कुछ प्रकार के उदाहरण आधारित स्विच स्टेटमेंट करें? – 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){ 

    } 

}