2009-06-28 11 views
25

यह सादा जावा में प्रोग्राम के रूप में कार्यावधि में एक वर्ग की एक विधि ओवरराइड करने के लिए संभव है (या यहां तक ​​कि एक नई विधि बनाने)?जावा प्रतिबिंब: मैं रनटाइम पर तरीकों को ओवरराइड या जेनरेट कैसे करूं?

मैं ऐसा करने में सक्षम होना चाहता हूं भले ही मैं संकलन समय पर कक्षाओं को जानता हूं।

क्या मैं कार्यावधि में अधिभावी द्वारा वास्तव में मतलब है:

abstract class MyClass{ 
    public void myMethod(); 
} 

class Overrider extends MyClass{ 
    @Override 
    public void myMethod(){} 
} 

class Injector{ 
    public static void myMethod(){ // STATIC !!! 
    // do actual stuff 
    } 
} 

// some magic code goes here 
Overrider altered = doMagic(
    MyClass.class, Overrider.class, Injector.class); 

अब, यह मंगलाचरण ...

altered.myMethod(); 

... Injector.myMethod()के बजाय Overrider कहेंगे .myMethod()। क्योंकि "जादू" करने के बाद यह अलग वर्ग उदाहरण (यह Overrider है), (ताकि हम इसे स्थानीय क्षेत्रों तक पहुंचने से रोकने) से शुरू हो जाती है

Injector.myMethod(), स्थिर है।

+1

पर एक नज़र डालें क्या आप हमें बता सकते हैं कि आप किस प्रकार की वस्तुओं को ओवरराइड करना चाहते हैं? दूसरी नज़र में आपकी समस्या मुझे निर्भरता-इंजेक्शन प्रतिमान के उद्देश्य की याद दिलाती है। – akarnokd

उत्तर

8

इंटरफेस के लिए वहाँ java.lang.reflect.Proxy है।

कक्षाएं या तो आप एक तीसरे पक्ष के पुस्तकालय की जरूरत है या कोड का एक उचित सा लिखेंगे लिए। आम तौर पर गतिशील रूप से कक्षाएं बनाने के लिए परीक्षण के लिए मोक्स बनाना है।

वहाँ भी उपकरण एपीआई कि कक्षाओं के संशोधन की अनुमति देता है। आप कस्टम क्लास लोडर या बस डिस्क पर क्लास फाइलों के साथ कक्षाओं को भी संशोधित कर सकते हैं।

+0

@ टीएचएच: आपकी राय में, क्या इस मामले में एओपी या बीसीईएल शैली पुन: इंजीनियरिंग लागू होगी?मुझे वर्तमान में एक समान समस्या का सामना करना पड़ रहा है और यह तय नहीं कर सकता कि इसका क्या उपयोग करना है। – akarnokd

+1

एओपी बहुत सामान्य है। मैं बीसीईएल को एएसएम पसंद करता हूं। oxbow_lakes cglib का उल्लेख करता है, जिसे मैं नाम (और उपयोग नहीं किया गया) याद नहीं कर सका। –

0

अगर मैं मिल गया कोड पैदा करने के लिए cglib की तरह कुछ का उपयोग कर सकते यह सही है, मुख्य समस्या यह है कि चिंताओं आप कैसे एक स्थिर विधि प्रतिनिधि के माध्यम से (सी # में) की तरह पारित करने के लिए, है उदाहरण इंटरफ़ेस विधि।

आप इस आलेख को देख सकते हैं: A Java Programmer Looks at C# Delegates, जो आपको दिखाता है कि कैसे अपनी स्थिर विधि का संदर्भ प्राप्त करें और इसे आमंत्रित करें। फिर आप एक रैपर क्लास बना सकते हैं जो अपने कन्स्ट्रक्टर में स्थिर विधि नाम स्वीकार करता है, और उदाहरण विधि से स्थैतिक विधि का आह्वान करने के लिए आपकी बेस क्लास लागू करता है।

8

मैंने एक article for java.net लिखा है कि एक क्लास में लॉगिंग स्टेटमेंट को पारदर्शी रूप से जोड़ने के तरीके के बारे में जब जावा एजेंट का उपयोग करके क्लासलोडर द्वारा लोड किया जाता है।

यह जैवसिस्ट लाइब्रेरी का उपयोग बाइट कोड में हेरफेर करने के लिए करता है, जिसमें जैवसिस्ट कंपाइलर का उपयोग अतिरिक्त बाइटकोड उत्पन्न करने के लिए किया जाता है जिसे उपयुक्त जगह में डाला जाता है, और उसके बाद परिणामी वर्ग क्लासलोडर को प्रदान किया जाता है।

एक परिष्कृत संस्करण slf4j प्रोजेक्ट के साथ उपलब्ध है।

+0

अब कई सालों बाद, मैं इस दृष्टिकोण की सिफारिश नहीं करूंगा। अगर आपको इसकी ज़रूरत है, तो पहलू ओरिएंटेड प्रोग्रामिंग देखें। –

9

Java6 में किसी भी पहले से ही भरी हुई वर्ग को बदलने के लिए संभावना जोड़ा गया है। changes पर java.lang.instrument पैकेज

+0

मैं यह भी भूल गया कि यह पैकेज मौजूद है! धन्यवाद! –

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