जबकि पॉलिमॉर्फिज्म का मुख्य सिद्धांत types
की अवधि में "किस से" है, लेकिन मुझे क्या भ्रमित करता है कि विधि-कॉल तंत्र कैसे पाता है और पॉलिमॉर्फिज्म में सही विधि निकाय को कॉल करता है।Java Determine विधियों को polymorphism में रनटाइम पर कैसे कॉल करता है?
के बाद से जावा में सभी विधि बाध्यकारी late-binding
है, जब तक विधि static
, final
या private
है, और देर से बाध्यकारी JVM जो प्रत्येक वर्ग के लिए method table
precomputes और फिर एक मेज सामान्य विधि कॉल में रनटाइम के दौरान ऊपर देखो करना द्वारा किया जाता है।
लेकिन यह भी पॉलिमॉर्फिज्म के दौरान होता है। उदाहरण
मान लीजिए के लिए मैं एक ride()
विधि
class Cycle {
public void ride(){
System.out.println("I'm Riding generic Cycle()");
}
}
के साथ एक सामान्य वर्ग Cycle
है और मैं तीन विशेष कक्षा Bicycle
Tricycle
और Unicycle
जो सामान्य वर्ग Cycle
प्रदान करता है और अपने ride()
विधि को ओवरराइड करता है।
class Bicycle extends Cycle {
public void ride() {
System.out.println("I'm riding Bicycle");
}
}
class Tricycle extends Cycle{
public void ride() {
System.out.println("I'm riding Tricycle ");
}
}
class Unicycle extends Cycle {
public void ride() {
System.out.println("I'm Riding Unicycle ");
}
}
यह TestRide
श्रेणी से ऊपर बहुरूपता का परीक्षण करने के लिए है।
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=5, args_size=1
0: new #17 // class com/polymorphism/Cycle
3: dup
4: invokespecial #24 // Method com/polymorphism/Cycle."
<init>":()V
7: astore_1
8: aload_1
9: invokestatic #25 // Method ride:(Lcom/polymorphism/
Cycle;)V
12: new #27 // class com/polymorphism/Bicycle
15: dup
16: invokespecial #29 // Method com/polymorphism/Bicycle
."<init>":()V
19: astore_2
20: aload_2
21: invokestatic #25 // Method ride:(Lcom/polymorphism/
Cycle;)V
24: new #30 // class com/polymorphism/Tricycle
27: dup
28: invokespecial #32 // Method com/polymorphism/Tricycl
e."<init>":()V
31: astore_3
32: aload_3
33: invokestatic #25 // Method ride:(Lcom/polymorphism/
Cycle;)V
36: new #33 // class com/polymorphism/Unicycle
39: dup
40: invokespecial #35 // Method com/polymorphism/Unicycl
e."<init>":()V
43: astore 4
45: aload 4
47: invokestatic #25 // Method ride:(Lcom/polymorphism/
Cycle;)V
50: return
भी बाईटकोड में अपनी बस invokestatic
और invokespecial
साथ सामान्य विधि कॉल के रूप में जब मैं सोचा था कि यह invokedynamic
आंकड़ा करने के लिए प्रयोग करेंगे:
public class TestRide {
public static void ride(Cycle c){
c.ride();
}
public static void main(String[] args){
Cycle Cycling = new Cycle();
ride(Cycling);
Bicycle bi = new Bicycle();
ride(bi);
Tricycle tri = new Tricycle();
ride(tri);
Unicycle uni = new Unicycle();
ride(uni);
}
}
आउटपुट
I'm Riding generic Cycle()
I'm riding Bicycle
I'm riding Tricycle
I'm Riding Unicycle
बाइट कोड है उस विधि के संस्करण को बाहर करें जो वस्तु के वास्तविक प्रकार के लिए उपयुक्त है। लेकिन बात वो नहीं थी।
तो कैसे जावा बहुरूपता के दौरान वास्तविक विधि कॉल यह पता लगाने करता है, जबकि हम सिर्फ TestRide
कक्षा में ride()
विधि ride(bi)
की तरह में एक upcasted वस्तु पारित?
संपादित करें: दी राइड विधि बाईटकोड
public static void ride(com.polymorphism.Cycle);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokevirtual #16 // Method com/polymorphism/Cycle.r
ide:()V
4: return
शायद आपका परीक्षण केस बहुत आसान है। यदि जावा कंपाइलर संकलन-समय पर जानता है, तो किस विधि को बुलाया जाएगा, बाइटकोड की कोई आवश्यकता नहीं है जो गतिशील रूप से कुछ भी करता है। – mastov
'invokedynamic' को गतिशील विधि लुकअप के लिए जेवीएम बाइटकोड में पेश किया गया था जो * जावा की विधि लुकअप का पालन नहीं करता है। जावा कंपाइलर इसका उपयोग क्यों करेगा? वर्चुअल विधि प्रेषण 'invokevirtual' और' invokeinterface' के साथ किया जाता है। ध्यान दें कि जावा कंपाइलर निश्चित रूप से 'invokedynamic' का उपयोग करने के लिए स्वतंत्र है यदि वह चाहता है। जावा लैंग्वेज स्पेसिफिकेशन जावा के संकलन के बारे में कुछ भी नहीं कहता है, यह भी नहीं कहता कि इसे संकलित किया जाना चाहिए, यह भी व्याख्या की जा सकती है। –
@ JörgWMittag अपना अंक मिला :)। लेकिन यह सवाल अभी भी –