2009-11-10 5 views
6

मैं क्या करना चाहता हूं कक्षाओं के सेट को लोड करना है, शायद सभी एक ही फ़ोल्डर में। जिनमें से सभी एक ही इंटरफेस को लागू करते हैं और एक ही कक्षा हैं, फिर मेरे कोड में मैं उन वर्गों पर कार्यों को कॉल करने में सक्षम होना चाहता हूं।जावा: गतिशील रूप से समान वर्ग के कई संस्करणों को लोड करें

+0

यह कस्टम के साथ खेल खेल के बिना संभव नहीं है क्लासलोडर (और तब भी संभव नहीं हो सकता है)। हो सकता है कि अगर आपने समझाया कि आप क्या हासिल करने की कोशिश कर रहे हैं तो आपको और मदद मिलेगी। –

+0

ओएसजीआई बहुत दिलचस्प लग रहा है, शायद मैं इस समस्या को गलत तरीके से देख रहा हूं। कम सामान्य अर्थ में मैं जो हासिल करने की कोशिश कर रहा हूं वह यहां है। मेरे पास गेम ओवेयर का एक खोल है जो गेम मैकेनिक्स चलाता है। यह अन्य वर्गों को उन्हें खेल की स्थिति भेजकर और एक कदम लौटकर अपनी चाल बनाने के लिए कहता है। मैं एआईएस जिनमें से प्रत्येक अलग कोड है उसका एक फ़ोल्डर करना चाहते हैं, वहाँ इनमें से कई हो सकता है। शेल तब एआईएस के सभी एआईएस पर एक राउंड रॉबिन टूर्नामेंट चलाएगा और आउटपुट जो एआईएस के खिलाफ जीता था। – JonLeah

उत्तर

5

मेरे सवाल का जवाब के आधार पर EOF पर चुनते हैं, तो ऐसा लगता है आप एक खेल इंटरफ़ेस को परिभाषित करने और फिर प्लग करने के लिए चाहते हैं एआई कार्यान्वयन की किसी भी संख्या में, शायद एक .properties फ़ाइल से कॉन्फ़िगर किया गया है। यह एक एपीआई इंटरफ़ेस का काफी मानक उपयोग है।

आप एक EngineInterface एक विधि है कि खेल राज्य स्वीकार करता है और इस कदम रिटर्न प्रदान परिभाषित करते हैं। फिर आप कई कक्षाओं को परिभाषित करते हैं जो सभी इंजन इंटेरफेस को लागू करते हैं। आपका ड्राइवर कार्यान्वयन वर्गों के नाम पाने के लिए एक संपत्ति फ़ाइल पढ़ता है,() Class.forName के साथ उन्हें को दर्शाता है और एक सूची और/या नक्शे में उन्हें संग्रहीत करता है। फिर जब चालक हो जाता है यह बदले में प्रत्येक कार्यान्वयन का आह्वान और परिणाम का ट्रैक रखता अनुरोध करता है।

1
  1. आप OSGi, उपयोग कर सकते हैं अपने के रूप में सरल रूप में एक उंगली तड़क! ओएसजीआई में आप में कक्षा के एकाधिक छंद हैं। आपके पास सभी संस्करणों के साथ बंडल हैं।

  2. अन्यथा आप अभी भी अपने कस्टम क्लास लोडर को लिख सकते हैं जो दोनों कक्षाओं को पढ़ता है। ऐसा करने का एक तरीका इस तरह होगा। आप दो क्लासलोडर्स लिखते हैं, उनमें से एक कक्षा के एक संस्करण को लोड करता है और दूसरा कक्षा के दूसरे संस्करण को लोड करता है। अब कक्षा को लोड करने के लिए आप classloader1 या classloader2 चुनने की आवश्यकता के आधार पर। तो अब आप स्मृति में एक साथ लोड एक ही कक्षा के कई संस्करण भी हो सकते हैं।

नोट: यकीन है कि यह वास्तव में आप क्या करना चाहते है, आपकी समस्या को हल आ के अन्य तरीकों हो सकता है।

+0

मुझे ओजीआईआई हो सकती है? –

+0

@ जेसन ... मुझे आपको नहीं मिला :) –

+5

"एक उंगली को तोड़ने के समान सरल" ... यह ओएसजीआई के संबंध में एक बोल्ड स्टेटमेंट है। – Thilo

1

केवल ढांचा मैं जानता हूँ कि जो समर्थन नहीं करता है कि तुम क्या करने के बाद है OSGI हैं:

alt text http://blog.springsource.com/wp-content/uploads/2009/01/network.png

इसके नेटवर्क मॉडल, इस लेख "Exposing the boot classpath in OSGi" में वर्णित है, की अनुमति नहीं है कि

नेटवर्किंग मॉडल के साइड इफेक्ट्स (या लक्ष्य) में से एक प्रकार अलगाव या कक्षा संस्करण है: उसी वर्ग का एकाधिक संस्करण उसी वीएम के अंदर अच्छी तरह से सह-अस्तित्व में हो सकता है क्योंकि ईए ch एक अपने नेटवर्क में लोड किया गया है, इसकी अपनी जगह।

इस tutorial शुरुआत के लिए देखें और OSGi फ्रेमवर्क (जैसे Equinox, Knoplerfish या Apache Felix)

2

आप की तरह कुछ करने की कोशिश की है:

class Move; // some data type that is able to represent the AI's move. 

interface AI { 

    Move getMove(GameState state); 
}; 

AIOne implements AI; 
AITwo implements AI; 

प्रत्येक वर्ग एक चाल पैदा करने के लिए अपने स्वयं के एल्गोरिथ्म को लागू होगा, लेकिन कहा जाता है लेकिन

2

यह संभव है कि आप क्या चाहते करने के लिए आम तरीका द्वारा कहा जा सकता है OSGi साथ लेकिन आप एक कस्टम classloader इस्तेमाल कर सकते हैं। विचार आप वर्ग आप लोड करना चाहते हैं के हर संस्करण के लिए एक classloader instanciate करना है।Here आप एक अच्छा स्पष्टीकरण पा सकते हैं।

लेकिन मुझे लगता है कि क्या तुम सच में हल करने के लिए आपकी समस्या इंटरफेस के आधार पर जिम गैरीसन या डेव एल डेलाने द्वारा वर्णित की तरह कुछ है जरूरत है ...

0

यह गतिशील वर्ग लोड हो रहा है का उपयोग किया जा सकता है। यह विभिन्न संस्करणों की श्रेणी लोड नहीं कर रहा है लेकिन एक सुपर क्लास या इंटरफेस के विभिन्न उप-वर्गों को लोड नहीं कर रहा है।

महत्वपूर्ण कदम हैं:

(1) का प्रयोग करें Class.forName (...) नाम से एक वर्ग लोड करने के लिए। कक्षा कक्षा पथ में होना चाहिए।

(2) का प्रयोग करें aClass.newInstance() वस्तु का दृष्टांत के लिए। यह आसान है अगर कन्स्ट्रक्टर के लिए कोई पैरामीटर आवश्यक नहीं है।

निम्नलिखित कोड आप के लिए कुछ विचार प्रदान करना चाहिए। यह अपवाद को संभाल नहीं करता है जिसे आपको करना है।

class Context { 
    void moveUp(); 
    void moveDown(); 
    ... 
} 

interface AI { 
    void action(Context con); 
} 

public class Game { 
    public Game() { 
     Context aContext = new Context(); 
     String[] aAIClsNames = this.getAIClassNames("ai.list"); 
     AI[]  aAIs  = this.loadAI(aAIClsNames); 
     this.run(aAIs); 
    } 
    String[] getAIClassNames(String pAIClassListFile) { 
     // .. Load the file containning the AI-class file names 
    } 
    AI[] loadAI(String[] pAIClsNames) { 
     AI[] AIs = new AI[pAIClsNames.length]; 
     for(int i = 0; i < pAIClsNames.length; i++) { 
      String aAIClsName  = pAIClsNames[i]; 

      // (1) Get the class by name 
      Class<? extends AI> aAICls = Class.forName(aAIClsName); 

      // (2) Notice the cast as all of class in the list must implements AI 
      AIs[i] = (AI)aAICls.newInstance(); 
     } 
     return AIs; 
    } 
    void run(AI[] pAIs) { 
     // ... 
    } 
} 

उम्मीद है कि इससे मदद मिलती है।

0

जिम की प्रतिक्रिया अच्छा है - आप वर्गों का उपयोग करना चाहते नाम, और वे सभी एक आम एपीआई के अनुरूप हैं। हालांकि दिया गया समाधान मानता है कि कक्षाएं पहले से ही आवेदन के कक्षा में उपलब्ध हैं। आप बाद में अधिक कार्यान्वयन जोड़ने में सक्षम होना चाहते हैं, उदा। आवेदन स्थापित होने के बाद।

thats मामले हैं, तो आप शायद एक कस्टम classloader का उपयोग करना होगा। उदाहरण के लिए, आप लोगों को कहीं किसी विशेष फ़ोल्डर के अंदर जार फ़ाइलों को रखने की अनुमति दे सकते हैं, और गुण फ़ाइल के कार्यान्वयन के वर्ग नाम जोड़ सकते हैं। की तुलना में है कि फ़ोल्डर के अंदर जार से कक्षाओं लोड कर सकते हैं तब आप एक कस्टम classloader की आवश्यकता होगी, और आप उस classloader का उपयोग वर्गों (जैसे Class.forName (className, classloader) का प्रयोग करके) लोड करने के लिए होगा।

तथ्य अगर आप जार फ़ाइल प्रति एक classloader है में, आप के रूप में classloader वर्ग के नाम सीमाओं को परिभाषित करता है, जार फ़ाइलों में एक ही नाम के साथ कई वर्गों के लिए सक्षम हो जाएगा। ओएसजीआई क्या कर रहा है यह काफी है।

यहाँ जार से लोड हो रहा है वर्गों से संबंधित कुछ कोड है:

http://sourceforge.net/projects/jcloader/ http://www.javaworld.com/javatips/jw-javatip70.html

संबंधित मुद्दे