2016-09-21 8 views
8

मुझे इस कोड को काम करने के लिए क्या करना है, इस बारे में मुझे परेशान है। ऐसा लगता है जैसे संकलक ने मुझे एक प्रकार के रूपांतरण को अनुकूलित किया है, या मुझे कुछ और समझ में नहीं आता है।कंपाइलर मेरे प्रकार के रूपांतरण को छोड़ रहा है?

मेरे पास डेटाबेस में संग्रहीत विभिन्न ऑब्जेक्ट्स हैं जो इंटरफ़ेस Foo को कार्यान्वित करते हैं। मेरे पास एक ऑब्जेक्ट है, bar, जिसमें डेटा है जो मैं अपने Foo ऑब्जेक्ट्स को पुनर्प्राप्त करने के लिए उपयोग कर रहा हूं।

public <T> T get(Class<T> clazz, Serializable id); 

वहाँ अलग अलग हैं:

Class getFooClass() 

Long getFooId() 

मैं इस हस्ताक्षर है, जो प्रतिनिधियों हाइबरनेट करने के लिए जो अपने वर्ग और आईडी के आधार पर विषय को पुन: प्राप्त के साथ एक विधि के लिए वर्ग और आईडी पारित: bar इन तरीकों है Foo के कार्यान्वयनकर्ता, और इनमें से कुछ हाइबरनेट वस्तुओं में Long आईडी है, और अन्य के पास Integer आईडी है। यद्यपि यह विधि या तो स्वीकार करती है, फिर भी नीचे बेहतर यह सही था। तो जब मैं एक Integer आईडी के साथ एक वस्तु पर get() कॉल करने की कोशिश, इस प्रकार, मैं जाहिर शिकायत है कि मैं एक Long जहां एक Integer आवश्यक था मुहैया कराई थी एक त्रुटि मिली:

get(bar.getFooClass(), bar.getFooId()); 

कोई हाइबरनेट समस्या यहाँ है, मैं बस Integer प्रदान करने की आवश्यकता है जहां Integer आईडी आवश्यक है और Long जहां Long आईडी आवश्यक है। इसलिए मैं bar के लिए एक विधि कहा, hasLongId(), और यह करने की कोशिश की: (इस बिंदु पर आप सोच रहे होंगे कि यह एक अच्छा डिजाइन नहीं है, लेकिन है कि मेरे सवाल नहीं है अभी)

get(bar.getFooClass(), 
    bar.hasLongId() ? bar.getFooId() : bar.getFooId().intValue()); 

और यह अभी भी है कि शिकायत की मैंने Long प्रदान किया था। वह अजीब लग रहा था। फिर मैंने यह कोशिश की:

get(bar.getFooClass(), 
    bar.hasLongId() ? bar.getFooId() 
        : new Integer(bar.getFooId().intValue())); 

वही त्रुटि! यह कैसे हो सकता है? इसलिए मैंने डीबगर में कदम रखा, और हां, यह intValue() और Integer कन्स्ट्रक्टर के माध्यम से भी चला गया, लेकिन फिर विधि प्राप्त करने में, पारित पैरामीटर वास्तव में Long-उसी Long ऑब्जेक्ट को getFooId() से वापस कर दिया गया था।

मुझे समझ नहीं नहीं क्या हो रहा है, तो मैं बस विभिन्न चीजों की कोशिश:

Integer intId = bar.getFooId().intValue(); 
get(bar.getFooClass(), bar.hasLongId() ? bar.getFooId() : intId); 
// same error 

और

Serializable id = bar.hasLongId() ? bar.getFooId() 
           : new Integer(bar.getFooId().intValue()); 
get(bar.getFooClass(), id); 
// same error 

और अंत में:

Serializable id; 
if (bar.hasLongId()) { 
    id = bar.getFooId(); 
} else { 
    id = bar.getFooId().intValue(); 
} 
get(bar.getFooClass(), id); 

यह एक काम करता है। तो स्पष्ट रूप से यह टर्नरी ऑपरेटर के साथ कुछ करने के लिए है। पर क्यों? क्या कोई समझा सकता है कि यहां क्या हुआ?

+6

पर्याप्त जानकारी नहीं है। कोड को पैराफ्रेश न करें और त्रुटि संदेशों को सारांशित न करें। मैं जो कुछ भी आपको दिया है उसके आधार पर क्या गलत है, यह पता लगाने में सक्षम नहीं हो सकता है, लेकिन मैं इस पर अधिक समय नहीं बिताने वाला हूं क्योंकि मैं बता सकता हूं कि आपने हमें कुछ भी पूरा नहीं किया है। – arcy

+0

आपके प्रश्न से संबंधित नहीं है, लेकिन आप अतिरिक्त विधि के बजाय 'getFooId() '' संख्या' क्यों नहीं लौटाते हैं और रूपांतरण टाइप करते हैं? – shmosel

+1

फिर से खोलने के लिए वोटिंग क्योंकि दूसरा प्रश्न टर्नरी एक्सप्रेशन या बॉक्स किए गए मानों पर चर्चा नहीं करता है। – shmosel

उत्तर

10

यह एक अच्छा सवाल है और टर्नरी अभिव्यक्ति के अर्थशास्त्र के किरदार के विवरण में जाता है। नहीं, आपका कंपाइलर टूटा नहीं है या आप पर चाल चल रहा है।

इस मामले में, अगर त्रिगुट अभिव्यक्ति के दूसरे और तीसरे ऑपरेंड के प्रकार long और int है, तो जिसके परिणामस्वरूप प्रकार हमेशा long है। यह binary numeric promotion के कारण है।

JLS (Java Language Specification) के अनुसार:

..., बाइनरी संख्यात्मक पदोन्नति संकार्य प्रकार के लिए लागू है, और सशर्त अभिव्यक्ति के प्रकार दूसरे और तीसरे ऑपरेंड के पदोन्नत प्रकार है।

मूल्यों नियम # बाइनरी संख्यात्मक का 1 संवर्धन के कारण अनबॉक्स्ड हो रही है:

किसी भी संकार्य एक संदर्भ प्रकार की है, तो यह अधीन है unboxing रूपांतरण के लिए

इसका अर्थ अनिवार्य रूप से है, कि जब आपके पास एक टर्नरी अभिव्यक्ति होती है, तो अभिव्यक्ति के परिणामी प्रकार को स्थिर रूप से निर्धारित किया जाना चाहिए (संकलन समय पर)। दूसरे और तीसरे ऑपरेशंस को एक ही प्रकार में घुमाया जाना चाहिए, जो अभिव्यक्ति का प्रकार है। यदि दोनों ऑपरेंड एक संख्यात्मक प्रकार हैं, तो बाइनरी न्यूमेरिक प्रमोशन अभिव्यक्ति के अंतिम प्रकार को निर्धारित करने के लिए किक करता है।

+0

स्पष्ट रूप से बॉक्स किए गए प्रकार के बारे में क्या? क्या यह अनबॉक्स हो रहा है? क्यूं कर? – shmosel

+0

अच्छा जवाब। यह अधिक पूरा हो जाएगा, जैसा कि @ श्मोसेल ने उल्लेख किया है कि कंपाइलर क्यों है, जब 'स्थिति' के साथ टर्नरी ऑपरेटर का सामना करना पड़ता है? लंबा: int 'या' शर्त? लांग: इंटेगर ',' लांग 'को' हालत 'बनाने के लिए ऑटो-अनबॉक्स को लॉन्च करने का निर्णय ले रहा है? लंबा: int'। फॉर्म 'हालत? लंबा: इंटीजर' भी वैध होना चाहिए? –

+0

उपरोक्त प्रश्नों के उत्तर देने के लिए संपादित किया गया। –

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