2010-05-03 11 views
7

जावा किसी दिए गए इंटरफ़ेस के लिए प्रॉक्सी क्लास उत्पन्न करता है और प्रॉक्सी क्लास का उदाहरण प्रदान करता है। लेकिन जब हम प्रॉक्सी ऑब्जेक्ट को हमारे विशिष्ट ऑब्जेक्ट में डालते हैं, तो जावा इसे आंतरिक रूप से कैसे संभालता है? क्या यह विशेष परिदृश्य के रूप में माना जाता है?जावा में कैसे उदाहरण और प्रकार कास्ट (i.e (ClassName)) प्रॉक्सी ऑब्जेक्ट पर काम करता है?

उदाहरण के लिए मैं कक्षा OriginalClass है और यह OriginalInterface लागू करता है, जब मैं प्रदान किए गए इंटरफ़ेस में OriginalInterface इंटरफ़ेस जावा बनाया प्रॉक्सी वर्ग ProxyClass तरीकों का उपयोग कर पारित करके प्रॉक्सी वस्तु बना सकते हैं और इस वर्ग के हैं (यानी। ProxyClass) की वस्तु प्रदान करता है। अगर मेरी समझ सही है तो आप प्रश्नों

  1. जब मैं अपने वर्ग OriginalClass इस काम करता है के लिए ProxyClass की वस्तु डाली प्रकार है, लेकिन कैसे जावा इस अनुमति दे रहा है निम्नलिखित का उत्तर दें कर सकते हैं? इंस्टेंस के मामले में वही?
  2. मेरे ज्ञान के रूप में जावा केवल विधियों के साथ प्रॉक्सी क्लास बनाता है, लेकिन जब मैं इस ऑब्जेक्ट पर विशेषताओं तक पहुंचने का प्रयास करता हूं तो क्या होता है?
  3. प्रॉक्सी में केवल इंटरफ़ेस विधियां लागू की जा रही हैं, लेकिन जब मैं एक ऐसी विधि तक पहुंचने का प्रयास करता हूं जो इंटरफ़ेस में नहीं है और केवल कक्षा में उल्लिखित है?

धन्यवाद, छात्र

+1

क्या आप शर्मिंदा हैं कि आपकी प्रॉक्सी को मूल क्लास कार्यों में कास्टिंग करें? मेरी समझ में यदि आपने मूल इंटरफेस के लिए प्रॉक्सी बनाई है तो आपको OriginalClass –

उत्तर

11

जावा किसी प्रॉक्सी से एक ठोस वर्ग के लिए कास्टिंग की अनुमति नहीं दे रहा है। जेडीके प्रॉक्सी (java.lang.reflect.Proxy) केवल एक इंटरफेस के प्रॉक्सी हैं। जिसके परिणामस्वरूप प्रॉक्सी प्रकार ProxyX (एक्स एक नंबर किया जा रहा है) की है, और अगर आप किसी भी वर्ग के लिए यह कास्ट करने के लिए प्रयास करते समय आपको ClassCastException

मिल जाएगा इसलिए अपने 2 और 3 सवाल प्रासंगिक नहीं हैं - प्रॉक्सी के द्वारा समर्थित नहीं है एक ठोस वर्ग इसे प्राप्त करने के लिए, आप अन्य प्रॉक्सी तंत्र का उपयोग कर सकते हैं - सीजीएलआईबी या जावासवादी। वे यमिक सबक्लासिंग का उपयोग करते हैं, और इसलिए सभी protected (और ऊपर) फ़ील्ड और विधियां सबक्लास (प्रॉक्सी) के लिए सुलभ हैं।

+0

पर कास्ट करने में सक्षम नहीं होना चाहिए, आपके त्वरित उत्तर के लिए बहुत बहुत धन्यवाद। जावा ठोस वर्ग में डालने की इजाजत नहीं दे रहा है। – learner

7

java.lang.reflect.InvocationHandler के लिए एपीआई javadocs से:

InvocationHandler एक प्रॉक्सी उदाहरण के आह्वान के संचालक द्वारा कार्यान्वित इंटरफेस है।

गतिशील प्रॉक्सी इंटरफ़ेस लागू करता है, लेकिन विधियों के मूल कार्यान्वयन प्रदान करने के लिए हैंडलर (OriginalClass) का उपयोग करता है।

आपके सवालों के जवाब के लिए:

  1. संकलक आप जब तक यह निश्चित है कि कलाकारों के सफल नहीं हो सकते होने के लिए पर्याप्त जानकारी नहीं है डाली करने देगा। गतिशील प्रॉक्सी के लिए परीक्षण और उदाहरण परीक्षण के रनटाइम व्यवहार javaadoc में java.lang.reflect.Proxy के लिए वर्णित है। यदि इंटरफ़ेस के साथ उपयोग किया जाता है, तो परीक्षणों का उदाहरण और उदाहरण सफल होगा, लेकिन कक्षाओं के साथ उपयोग नहीं किया जाता है।
  2. आप डायनामिक प्रॉक्सी का उपयोग करके किसी भी विशेषता का उपयोग नहीं कर सकते क्योंकि यह इंटरफ़ेस लागू करता है, यह हैंडलर क्लास का विस्तार नहीं करता है।
  3. आप डायनामिक प्रॉक्सी का उपयोग करके इंटरफ़ेस में घोषित नहीं किए गए किसी भी तरीके तक नहीं पहुंच सकते हैं क्योंकि यह इंटरफ़ेस लागू करता है, यह हैंडलर क्लास का विस्तार नहीं करता है।

गतिशील प्रॉक्सी के कार्यान्वयन के अंदर (उदाहरण के लिए आमंत्रण के कार्यान्वयन में ...) विधि) आप प्रतिबिंब का उपयोग कर हैंडलर के सदस्यों तक पहुंच सकते हैं।

// package ...; 

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 

import junit.framework.Assert; 

import org.junit.Test; 

public class TestDynamicProxy 
{ 
    @Test 
    public void testCast() throws Exception { 
     Foo foo = (Foo) TestProxy.newInstance(new FooImpl()); 
     foo.bar(null); 

     System.out.println("Class: " + foo.getClass()); 
     System.out.println("Interfaces: " + foo.getClass().getInterfaces()); 

     Assert.assertNotNull(foo); 
     Assert.assertTrue(foo instanceof Foo); 
     Assert.assertFalse(foo instanceof FooImpl); 
    } 
} 

interface Foo 
{ 
    Object bar(Object obj) throws Exception; 
} 

class FooImpl implements Foo 
{ 
    public Object bar(Object obj) throws Exception { 
     return null; 
    } 
} 

class TestProxy implements java.lang.reflect.InvocationHandler 
{ 
    private final Object obj; 

    public static Object newInstance(Object obj) { 
     return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new TestProxy(obj)); 
    } 

    private TestProxy(Object obj) { 
     this.obj = obj; 
    } 

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 
     Object result; 

     try { 
      result = m.invoke(obj, args); 
     } 
     catch (InvocationTargetException e) { 
      throw e.getTargetException(); 
     } 
     catch (Exception e) { 
      throw new RuntimeException("unexpected invocation exception: " + e.getMessage()); 
     } 

     return result; 
    } 
} 

यह article उपयोगी जानकारी और उदाहरण कोड का एक बहुत कुछ है:

यहाँ कुछ परीक्षण कोड है कि मैं अपने जवाब की जांच करने के लिए प्रयोग किया जाता है।

+0

बहुत बहुत धन्यवाद। आपकी जानकारी बहुत उपयोगी है। – learner

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