प्रत्येक जावा क्लास वर्चुअल विधि तालिका से जुड़ी है जिसमें कक्षा के प्रत्येक विधि के बाइटकोड में "लिंक" होते हैं। वह तालिका किसी विशेष वर्ग के सुपरक्लास से विरासत में प्राप्त होती है और उप-वर्ग के नए तरीकों के संबंध में विस्तारित होती है। उदाहरण के लिए, तालिका में
class BaseClass {
public void method1() { }
public void method2() { }
public void method3() { }
}
class NextClass extends BaseClass {
public void method2() { } // overridden from BaseClass
public void method4() { }
}
परिणाम
BaseClass
1. BaseClass/method1()
2. BaseClass/method2()
3. BaseClass/method3()
NextClass
1. BaseClass/method1()
2. NextClass/method2()
3. BaseClass/method3()
4. NextClass/method4()
ध्यान दें, कैसे NextClass
की आभासी विधि तालिका BaseClass
की मेज की प्रविष्टियों के आदेश को बरकरार रखे हुए है और बस method2()
के "लिंक" अधिलेखित कर देता है जो यह ओवरराइड करता है।
JVM का एक कार्यान्वयन इस प्रकार याद है कि BaseClass/method3()
हमेशा किसी भी वस्तु इस विधि कभी पर सक्रिय किया जाएगा की आभासी विधि तालिका में तीसरे प्रविष्टि होगी द्वारा invokevirtual
के लिए एक कॉल अनुकूलन कर सकते हैं।
invokeinterface
के साथ यह अनुकूलन संभव नहीं है। जैसे, आभासी विधि टेबल
AnotherClass
1. BaseClass/method1()
2. NextClass/method2()
3. BaseClass/method3()
4. AnotherClass/method4()
5. MyInterface/ifaceMethod()
MyClass
1. MyClass/method5()
2. MyInterface/ifaceMethod()
आप देख सकते हैं में
interface MyInterface {
void ifaceMethod();
}
class AnotherClass extends NextClass implements MyInterface {
public void method4() { } // overridden from NextClass
public void ifaceMethod() { }
}
class MyClass implements MyInterface {
public void method5() { }
public void ifaceMethod() { }
}
इस वर्ग पदानुक्रम परिणाम, AnotherClass
अपने पांचवें प्रविष्टि में इंटरफेस की विधि शामिल है और MyClass
अपनी दूसरी प्रविष्टि में यह होता है। वर्चुअल विधि तालिका में वास्तव में सही प्रविष्टि को खोजने के लिए, invokeinterface
वाली विधि के लिए कॉल को हमेशा ऑप्टिमाइज़ेशन की शैली के बिना पूरी तालिका को खोजना होगा, जो कि invokevirtual
करता है।
इस तथ्य के अतिरिक्त अंतर हैं कि invokeinterface
ऑब्जेक्ट संदर्भों के साथ एक साथ उपयोग किया जा सकता है जो वास्तव में इंटरफ़ेस को लागू नहीं करता है।इसलिए, invokeinterface
को रनटाइम पर जांचना होगा कि तालिका में कोई विधि मौजूद है या संभावित रूप से अपवाद फेंकना है। यदि आप विषय में गहराई से गोता लगाने के लिए चाहते हैं, तो मैं सुझाव देता हूं, उदाहरण के लिए, "Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless"।
देखें [जावा इंटरफेस का प्रभावशाली कार्यान्वयन: Invokeinterface माना जाता है] [http://www.research.ibm.com/people/d/dgrove/papers/oopsla01.pdf)। –
इसमें वर्चुअल विधियों की एक तालिका है। तालिका स्वयं वर्चुअल नहीं है;) –