2012-12-08 23 views
11

जावा पर, क्या आप reflection का उपयोग करके बनाए गए वर्ग में विधियों को ओवरराइड करना संभव है?जब मैं प्रतिबिंब के माध्यम से ऑब्जेक्ट बनाता हूं तो मैं जावा में विधियों को ओवरराइड कैसे कर सकता हूं?

public class MyObject 
{ 
    public String foo, bar; 

    public MyObject(String foo) 
    { 
     this.foo = foo; 
     this.bar = foo + "bar"; 
    } 

    public void setBar(String bar) 
    { 
     this.bar = bar; 
    } 
} 

और एक कक्षा में मैं इस प्रकार यह सीधे बना सकते हैं और अपने setBar विधि ओवरराइड करना चाहते:

MyObject obj = new MyObject("something") 
{ 
    @Override 
    public void setBar(String bar) 
    { 
     this.bar = this.foo; 
    } 
}; 

वहाँ एक विधि ओवरराइड करने के लिए एक रास्ता है उदाहरण के लिए, मैं निम्नलिखित वर्ग है कहना प्रतिबिंब का उपयोग कर इसी तरह से? शायद ऐसा कुछ? :

Class<?> _class = Class.forName("com.example.MyObject"); 
Constructor<?> _constructor = _class.getConstructor(new Class<?>[]{String.class}); 
Method m = _class.getMethod("setBar", new Class<?>[]{String.class}); 
Object obj = _constructor.newInstance("Foo String") 
{ 
    m = new Method(new Class<?>[]{String.class}) 
    { 
     System.out.println("Foobar"); 
    } 
}; 

यदि नहीं, तो ऐसा करने के अन्य तरीके हैं, या बाहरी पुस्तकालय जो मदद कर सकता है? मैं बाध्य मूल्यों को बदलने के लिए श्रोताओं को एक सेटर विधि में जोड़ने का तरीका ढूंढ रहा हूं।

+1

आपको गतिशील कोड जनरेशन लाइब्रेरी की आवश्यकता है, जैसे * javassist *। –

उत्तर

10

नहीं, यह आपके उदाहरण के रास्ते में संभव नहीं है।

अपने उदाहरण में, जावा कम्पाइलर दो अलग-अलग वर्गों पैदा करेगा:

MyObject.class 
MyObject$1.class 

बाद ओवरराइड विधि के साथ एक होने के। इस मामले में, यह एक गुमनाम आंतरिक वर्ग (Java tutorial documentation देखें)

है लेकिन वहाँ और अधिक जटिल बाईटकोड बुनाई पुस्तकालयों को शामिल समाधान है। Cglib, asm, javassist इत्यादि जैसे पुस्तकालय आपको गतिशील रूप से रनटाइम पर नई कक्षाएं बनाने और उन्हें लोड करने की सुविधा देते हैं।

जैवसिस्ट के पास add methods to classes at runtime पर एक ट्यूटोरियल है। विधि को जोड़ने/ओवरराइड करने के लिए इसे अनुकूलित करना संभव होना चाहिए:

CtClass origClazz = ClassPool.getDefault().get("org.example.MyObject"); 
CtClass subClass = ClassPool.getDefault().makeClass(cls.getName() + "New", origClazz); 
CtMethod m = CtNewMethod.make(
      "public void setBar(String bar) { this.bar = bar; }", 
      subClass); 
subClass .addMethod(m); 
Class clazz = cc.toClass(); 
+0

यह वही है जो मैं खोज रहा था - लेकिन मैं निश्चित रूप से इसे फिट कर सकता हूं। धन्यवाद! – Phil

0

नहीं, आप जो पूछ रहे हैं वह रनटाइम संकलन की तरह कुछ है। हालांकि असंभव नहीं है यह निश्चित रूप से कुछ नहीं है जो प्रतिबिंब API प्रदान करता है।

2

आप एक अंतरफलक प्रकार का ऑब्जेक्ट लौट रहे हैं तो आप Proxy.newProxyInstance का उपयोग एक अंतरफलक है कि गतिशील रूप से एक InvocationHandler वस्तु जो आप जो कुछ भी कस्टम व्यवहार आप चाहते हैं लिख सकते हैं विधि आमंत्रण भेजता का एक उदाहरण प्राप्त करने के लिए कर सकते हैं।

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

  • कोई संबंधित समस्या नहीं^_^