2012-06-15 15 views
13

दो दिनों में मैं जावा में एक परीक्षा है, और मैं इस सवाल का जवाब पता नहीं कर सकते हैं:जावा ओवरलोडिंग: संख्या, संख्या; पूर्णांक, डबल

class ClassA { 
public String foo(Integer x , int y) { 
    return "Integer, int"; 
} 
public String foo(int x, Double y) { 
    return "int, Double"; 
} 
public String foo(Number x, Number y) { 
    return "Number, Number"; 
} 
public String foo(Object x, Object y) { 
    return "Object, Object"; 
} 
public static void main(String... args) { 
    ClassA a = new ClassA(); 
    System.out.print(a.foo(5, 1.2f) + " "); 
    System.out.println(a.foo(null, null)); 
} 
} 

उत्पादन क्या है?

जवाब है:

Number, Number Number, Number 

मुझे पता है कि जावा हमेशा चुनता सबसे निर्दिष्ट विधि, यही वजह है कि a.foo(null,null);Number,Number विधि और नहीं Object,Object विधि envoke होगा। लेकिन a.foo(5,1.2f); भी Number,Number विधि को हल करता है और int,Double विधि नहीं है ??

लेकिन एक और बात जो उपयोगी हो सकता है: तो मैं हटाने f के बाद 1.2, ताकि कॉल है: a.foo(5,1.2); मैं एक संकलक त्रुटि मिलती है, कि यह Number,Number और int,Double विधि के बीच चयन नहीं कर सकते .. ।

, सच में मददगार होगा अगर तुम लोग मुझे लगता है कि समझा सकता है :)

+0

http://stackoverflow.com/a/9362386/368544 (यह बताते हैं अशक्त, नल)। फ्लोट केस मामूली है। – mschonaker

उत्तर

17

1.2f एक Double से लिपटे नहीं है, यह एक Float द्वारा लपेटा है। चूंकि FloatDouble का उप-वर्ग नहीं है (वे Number के विशिष्ट उप-वर्ग हैं), सबसे विशिष्ट विधि हस्ताक्षर का उपयोग किया जा सकता है foo(Number,Number) है।

एक बार जब आप f निकालने के लिए, 1.2 माना जाएगा एक double (आदिम, नहीं आवरण वर्ग) डिफ़ॉल्ट रूप से है, जो एक Double को autoboxed जा सकता है। हालांकि 5 को Integer पर भी ऑटोबॉक्साइड किया जा सकता है, जिससे अस्पष्टता उत्पन्न हो सकती है।

+1

ठीक है मुझे लगता है कि मैंने इसे समझा है :) इसलिए क्योंकि '1.2 एफ' को फ्लोट के रूप में माना जाता है, इसे केवल' फ्लोट 'के लिए' डबल 'पर ऑटोबॉक्ड किया जा सकता है। लेकिन अगर मैं 'डबल' से 'डबल' में बदलता हूं तो यह 'डबल' तक बढ़ने के कारण काम करता है जो रैपर वर्गों के साथ संभव नहीं है। – user1459010

4

यहां दो महत्वपूर्ण कारक हैं।

पहला, 1.2fDouble नहीं है। यह Float है। (int, Double) फ़ंक्शन बिल्कुल मेल नहीं खाता है। (Number, Number) सबसे अच्छा फिट है।

दूसरा, यहां तक ​​कि जब आप इसे 1.2 में बदलते हैं, तब भी यह Double नहीं है। यह double है। यही है, यह एक आदिम है, एक वस्तु नहीं। अब, जावा अभी भी खुशी से एक double एक समारोह है कि एक Double चाहता है ज्यादा बिना किसी शिकायत के में पारित होगा, लेकिन इस मामले में आप इसे दो रूपांतरण मान्य देकर यह भ्रमित किया है यह कर सकता है:

  1. एक Integer में कनवर्ट 5और एक आदिम int के रूप में एक Double
  2. छोड़ दो 5 को 1.2 रूपांतरित होते हैं लेकिन एक Double को 1.2 परिवर्तित।

कोई नियम नहीं है कि इनमें से कौन सा बेहतर है। जावा एक कंपाइलर त्रुटि उत्पन्न करता है जिसमें यह एक संदिग्ध फ़ंक्शन कॉल है, और आपको यह चुनने के लिए मजबूर करता है कि आप कौन सी पसंद करेंगे (मैन्युअल रूप से ऑब्जेक्ट्स में से एक या दोनों को लपेटकर)।

एक के रूप में अलग रूप में, यदि आप एक विधि है कि (int, double) ले लिया वहाँ कोई अस्पष्टता नहीं सब पर होगा था: उस विधि वास्तव में 5 और 1.2 की मौजूदा प्रकार से मेल खाता है, तो यह कहा जा सकता है। यह तथ्य यह है कि यहां कुछ तर्क रैपर ऑब्जेक्ट्स हैं जो तबाही का कारण बनते हैं।

1

जेनेरिक उत्तर:

public class OverloadingNumeric { 

    public void print(int x){ 
     System.out.println("int"); 
    } 

    public void print(long x){ 
     System.out.println("long"); 
    } 

    public void print(float x){ 
     System.out.println("float"); 
    } 

    public void print(double x){ 
     System.out.println("double"); 
    } 

    public void print(Integer x){ 
     System.out.println("Integer"); 
    } 

    public void print(Long x){ 
     System.out.println("Long"); 
    } 

    public void print(Float x){ 
     System.out.println("Float"); 
    } 

    public void print(Double x){ 
     System.out.println("Double"); 
    } 

    public void print(Number x){ 
     System.out.println("Double"); 
    } 

    public void print(Object x){ 
     System.out.println("Object"); 
    } 

    public static void main(String[] args) { 
     OverloadingNumeric obj = new OverloadingNumeric(); 
     /* 
     * Primitives will take more precedence 
     * of calling instead of wrapper class arguments, 
     */ 
     obj.print(10); 
     obj.print(10l); 
     obj.print(10f); 
     obj.print(10d); 
     obj.print(10.1); 
     //obj.print(999999999999999); Error: this letral type int is out of range 
     obj.print(999999999999999l); 

     /* 
     * OUTPUT 
     * int 
     * long 
     * float 
     * double 
     * double 
     * long 
     */ 



     /* 
     * Assume all primitive argument methods 
     * are commented. then calling the same again 
     */ 
     obj.print(10); 
     obj.print(10l); 
     obj.print(10f); 
     obj.print(10d); 
     obj.print(10.1); 

     //obj.print((Double)10); //Cannot cast int to Double 
     obj.print((double)10); //Success 
     //obj.print((Float)10); //Cannot cast int to Float 
     obj.print((float)10); //Success 
     //obj.print(null); ERROR AMBIGUOUS 

     /* 
     * OUTPUT 
     * Integer 
     * Long 
     * Float 
     * Double 
     * Double 
     * Double 
     * Float 
     * 
     */ 
    } 
} 




interface SuperIfc {} 

class SuperClass implements SuperIfc{} 

class SubClass extends SuperClass {} 

public class OverloadingTest { 

    public void print(SuperIfc x){ 
     System.out.println("SuperIfc"); 
    } 

    public void print(SuperClass x){ 
     System.out.println("SuperClass"); 
    } 

    public void print(SubClass x){ 
     System.out.println("SubClass"); 
    } 

    public void print(Object x){ 
     System.out.println("Object"); 
    } 

    public static void main(String[] args) { 
     OverloadingTest obj = new OverloadingTest(); 
     SuperClass superObj = new SuperClass(); 
     SubClass subObj = new SubClass(); 
     obj.print(superObj); 
     obj.print(subObj); 
     obj.print(null); 

     obj.print((SuperIfc)superObj); 
     obj.print((SuperIfc)subObj); 
     obj.print((SuperIfc)null); 
     /* 
     * OUTPUT 
     * SuperClass 
     * SubClass 
     * SubClass 
     * SuperIfc 
     * SuperIfc 
     * SuperIfc 
     */ 
    } 
} 
संबंधित मुद्दे