दिलचस्प पोस्ट
PHP में @ प्रतीक का क्या उपयोग है? TThreadedQueue कई उपभोक्ताओं के लिए सक्षम नहीं है? जीआईटी भंडार आकार कम करें मैं Python का उपयोग कर HTTP से अधिक फ़ाइल कैसे डाउनलोड करूं? याहू फाइनेंस यूआरएल काम नहीं कर रहा है एंड्रॉइड शेल के लिए एक्जीक्यूटेबल बिल्डिंग मैं एक PHP फार्म कैसे बना सकता हूं जो स्वयं को सबमिट करता है? स्ट्रीम क्यों करता है <टी> अस्थिर <T> लागू नहीं? क्या मुझे अपनी प्रोजेक्ट फाइल को संस्करण नियंत्रण में रखना चाहिए? पूंछ पुनर्कलन क्या है? जावास्क्रिप्ट या jQuery के साथ वर्तमान महीने की पहली और अंतिम तिथि प्राप्त करें एंड्रॉइड लंबित इंस्टेंट क्या है? C ++ में गणितीय अभिव्यक्तियों का मूल्यांकन करने का सबसे अच्छा तरीका क्या है? क्या जावा ऑडियो के लिए पुस्तकालयों में निर्मित है _ सिंघेसिस_? पूर्ण बनाम सापेक्ष स्थिति चौड़ाई और ऊंचाई

क्या एक जावा वर्ग रनटाइम पर खुद को एक विधि जोड़ सकता है?

क्या कोई क्लास रनटाइम पर अपने आप में एक विधि जोड़ सकता है (जैसे कि एक static ब्लॉक से), ताकि अगर कोई इस वर्ग पर प्रतिबिंब कर रहा है, तो वे नई पद्धति देखेंगे, भले ही समय संकलन में परिभाषित नहीं किया गया हो?

पृष्ठभूमि:

मैं उपयोग कर रहा हूँ एक रूपरेखा Action कक्षाओं परिभाषित करने के लिए उम्मीद है कि एक doAction(...) विधि है, सम्मेलन द्वारा। फ्रेमवर्क इन वर्गों को रनटाइम में निरीक्षण करता है कि उनके doAction() विधि में किस तरह के पैरामीटर उपलब्ध हैं। उदाहरण के लिए: doAction ( स्ट्रिंग ए, इंटिजर बी)

मैं चाहता हूं कि प्रत्येक श्रेणी को अपने पैरामीटर के साथ-साथ अपने doAction() विधि को उत्पन्न करने में सक्षम होना चाहिए, बस समय-समय पर इसका निरीक्षण किया जाए। विधि का शरीर खाली हो सकता है।

वेब के समाधान से एकत्रित समाधान "क्या एक जावा वर्ग रनटाइम पर खुद को एक विधि जोड़ सकता है?"

यह आसान नहीं है एक क्लास क्लासलोडर द्वारा क्लास लोड होने के बाद, लोड किए गए कक्षाओं के तरीकों को बदलने का कोई तरीका नहीं है। जब एक क्लास का अनुरोध किया जाता है, तो एक क्लासलोडर इसे लोड करेगा और उसे लिंक करेगा। लिंक किए गए कोड को बदलने या विधियों को जोड़ने / हटाने के लिए कोई रास्ता नहीं है (जावा के साथ)

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

  1. एक कस्टम क्लासलोडर को लागू करें
  2. उस कस्टम क्लासलोडर के साथ गतिशील कक्षा लोड करें
  3. अगर हमारे पास इस वर्ग का एक अद्यतन संस्करण है,
  4. कस्टम क्लासलोडर को हटा दें और
  5. कस्टम क्लासलोडर के एक नए उदाहरण के साथ इस वर्ग के नए संस्करण को लोड करें

मुझे लगता है कि सोचा के लिए भोजन के रूप में, साबित नहीं किया जा सकता है, अगर यह एक समाधान की ओर जाता है या अगर हमारे पास नुकसान हो

प्रश्न का एक सरल उत्तर के रूप में: नहीं, हम लोड किए गए वर्ग को बदल नहीं सकते हैं जैसे कि हम प्रतिबिंब वाले क्षेत्रों की सामग्री को बदल सकते हैं। (हम फ़ील्ड भी नहीं जोड़ सकते हैं या हटा सकते हैं)।

Andres_D सही है, हम कस्टम क्लास लोडिंग का उपयोग करके बहुत अच्छी तरह से कर सकते हैं, यहां यह कैसे करें यह एक विस्तृत गाइड है: http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic एचटीएमएल? page = 1

आलेख बताता है कि गतिशील जावा कोड कैसे लिखना है। इसमें रनटाइम स्रोत कोड संकलन, क्लास पुनः लोडिंग, और प्रॉक्सी डिज़ाइन पैटर्न के उपयोग को कॉल करने वाले डायनेमिक क्लास को पारदर्शी बनाने के लिए चर्चा करता है।

वास्तव में ऑस्ट्रिया में शोधकर्ता ने एक जेवीएम लिखा है जो विभिन्न प्रकार के पदानुक्रम के साथ कक्षाओं को फिर से लोड करने की अनुमति देता है। उन्होंने मौजूदा धागे को पॉइंट्स के जरिए एक वस्तु का पूरा 'साइड ब्रह्मांड' उत्पन्न करने और सभी संबंधित संदर्भ और संदर्भित सामग्री बनाने के लिए इसे हासिल कर लिया है और फिर एक बार पूरी तरह से सभी आवश्यक परिवर्तनों के साथ फिर से फेरबदल किए गए सभी बदलते वर्गों में स्वैप [1] यहां उनके प्रोजेक्ट http://ssw.jku.at/dcevm/ के लिए एक लिंक है जो ओरियल प्रायोजन निश्चित रूप से भविष्य की योजनाओं पर दिलचस्प अनुमान लगाता है।

विधि निकायों और क्षेत्रों में कम घुसपैठ के परिवर्तन जावा जावा में पेश किए गए जेपीडीए के हॉट स्वाद क्षमताओं का इस्तेमाल करते हुए मानक जावा वीएम में पहले से संभव है:
docs.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap

मुझे यकीन नहीं है कि यह पहला था, लेकिन 2001 से यह सन कर्मचारी का पेपर हॉटस्पॉट से हॉट स्वैप की क्षमताओं का उल्लेख करने वाले शुरुआती प्रस्तावों में से एक है। [2]

संदर्भ

[1] टी। वुमेमीररिंगर, सी। विमेर, और एल। स्टेपलर, "जावा के लिए डायनेमिक कोड इवोल्यूशन", जावा, विएना, 2010 में सिद्धांतों और प्रोग्रामिंग के अभ्यास पर 8 वीं अंतर्राष्ट्रीय सम्मेलन में पेश किया।

[2] एमओ। दिमित्रीव, "ओवालस स्तरीय इंजीनियरिंग के लिए ओओपीएसएलए वर्कशॉप ऑन इवोल्यूशन, 2001" में "जावा लैंग्वेज एप्लीकेशंस के रनटाइम विकास के लिए लचीला और सुरक्षित तकनीक की ओर"

मैंने खुद को बहुत कुछ पसंद नहीं किया है, लेकिन आपको एएसएम , सीग्लीब और जवासीस्ट पर नजर रखना चाहिए।

नहीं, यह जावा में संभव नहीं है (आसानी से)

ऐसा लगता है कि आप जावा का उपयोग करने की कोशिश कर रहे हैं जैसे कि यह एक गतिशील प्रोग्रामिंग भाषा है। उदाहरण के लिए, रूबी की खुली कक्षाएं हैं: आप रनटाइम पर रुबी कक्षाओं से तरीकों को जोड़ सकते हैं और हटा सकते हैं। रूबी में, आप भी अपनी कक्षा में एक विधि "अनुपलब्ध" विधि हो सकती है, जिसे आप क्लास में मौजूद नहीं होने वाले किसी विधि को कॉल करने का प्रयास करते समय कहा जाएगा। ऐसी बात भी जावा में मौजूद नहीं है

जेबीएम, जेरुबी पर चलने वाले रूबी का एक संस्करण है, और इसे जेवीएम पर ओपन क्लास का काम करने के लिए बहुत ही कठिन चाल करना है।

आप एक doAction विधि बना सकते हैं जो आपको करने के लिए बनाई जाने वाली विधि को पसंद करता है। क्या कोई कारण है कि इसे उत्पन्न करना आवश्यक है या क्या यह गतिशील हो सकता है?

मेरा मानना ​​है कि आपको कुछ बाइट कोड बदलने वाले टूल / फ्रेमवर्क की आवश्यकता है, जैसे कि asm, cglib या javassist आप इसे पहलुओं / बुनाई के माध्यम से प्राप्त कर सकते हैं जैसे कि यह वसंत किया गया है, लेकिन मेरा मानना ​​है कि आपको अभी भी इस पद्धति को परिभाषित करने की आवश्यकता है

प्रॉक्सी मदद कर सकता है लेकिन हर बार जब आप किसी विधि को जोड़ना या निकालना चाहते हैं, तो उसे एक प्रॉक्सी इन्स्तांत करना होगा

मुझे यकीन नहीं है कि यह संभव है। हालांकि, आप एपटेकज, एएसएम, आदि का इस्तेमाल कर सकते हैं और इन विधियों को उचित कक्षाओं में बांट सकते हैं।

दूसरा विकल्प लक्ष्य वर्ग को लपेटने के लिए संरचना का उपयोग करना है और डैएक्शन विधि प्रदान करना है। आप इस मामले में लक्ष्य वर्ग को नियुक्त कर देंगे।

ऐसा लगता है कि विधि को गतिशील रूप से जोड़ने का कोई तरीका नहीं है लेकिन आप किसी प्रकार की विधियों या एक हैश की सूची के साथ एक कक्षा तैयार कर सकते हैं:

 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; public class GenericClass { private HashMap<String, Method> methodMap = new HashMap<String, Method>(); public Object call(String methodName,Object ...args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method method = methodMap.get(methodName); return method.invoke(null, args); } public void add(String name,Method method){ if(Modifier.isStatic(method.getModifiers())) methodMap.put(name, method); } public static void main(String[] args) { try { GenericClass task = new GenericClass(); task.add("Name",Object.class.getMethod("Name", new Class<?>[0])); } catch (NoSuchMethodException | SecurityException e) { e.printStackTrace(); } } } 

इसके बजाय, प्रतिबिंबों का उपयोग करके आप विशेषता को सेट या अनसेट कर सकते हैं।