2016-03-25 5 views
5

निम्नलिखित कोड एक एंड्रॉइड लाइब्रेरी से है जिसे बुटरकिनीफ कहा जाता है। मैं यह पता लगा रहा हूं कि यह कैसे काम करता है।रिटर्न प्रकार के आधार पर जावा जेनरिक कास्ट?

@SuppressWarnings("unchecked") 
    public static <T> T cast(Object o){ 
     try { 
      return (T) o; 
     } catch (ClassCastException e){ 
      throw new AssertionError("Error"); 
     } 
    } 

और उपयोग::

@SuppressWarnings("unchecked") // That's the point. 
    public <T> T castParam(Object value, String from, int fromPosition, String to, int toPosition) { 
    try { 
     return (T) value; 
    } catch (ClassCastException e) { 
     throw new IllegalStateException("Parameter #" 
      + (fromPosition + 1) 
      + " of method '" 
      + from 
      + "' was of the wrong type for parameter #" 
      + (toPosition + 1) 
      + " of method '" 
      + to 
      + "'. See cause for more info.", e); 
    } 
    } 

मैं इस समारोह के व्यवहार को पुन: करने की कोशिश की

Object o = new String("test"); 
Double d = cast(o); 

लेकिन अपवाद कभी नहीं पकड़ा नहीं है, यह लाइन पर फेंक दिया जाता है जब विधि कहा जाता है। ऐसा क्यों है?

इसके अलावा, यह वास्तव में कैसे काम करता है? विधि कैसे पता चलेगी कि क्या डालना है?

उत्तर

2

रूप SJuan67 बताया गया है, तुम सच में उपयोग नहीं कर सकते जावा के रूप में सामान्य प्रकार के साथ डाले

उनकी सीमा या वस्तु के साथ सामान्य प्रकार के सभी प्रकार पैरामीटर का स्थान ले लेगा, तो प्रकार पैरामीटर असीम हैं। उत्पादित बाइटकोड, इसलिए, केवल सामान्य वर्ग, इंटरफेस, और विधियों में शामिल हैं।

सभी जेनेरिक प्रतिबंधों here पर अधिक जानकारी। अपने प्रश्नों के

public Object castParam(Object paramObject, String paramString1, int paramInt1, String paramString2, int paramInt2) 
    { 
    return paramObject; 
    } 

तो:

तो ButterKnife कोड इस तरह दिखेगा

प्रश्न: लेकिन अपवाद कभी नहीं पकड़ा नहीं है, यह लाइन पर फेंक दिया जाता है जब विधि कहा जाता है। ऐसा क्यों है?

ए: ठीक है यह बाइटकोड में भी नहीं है।

प्रश्न: इसके अलावा, यह वास्तव में कैसे काम करता है? विधि कैसे पता चलेगी कि क्या डालना है?

ए: ऐसा नहीं है। कम से कम ऐसा नहीं लगता कि आप करेंगे। व्यावहारिक रूप से यह क्लासकास्टएक्सप्शन को आपके द्वारा मनाए गए अवैध बिलकुल अपवाद या AssertionError को फेंक देगा। तुम भी ButterKnife नमूना अनुप्रयोग के साथ यह कोशिश करते हैं और चेकबॉक्स के एक ज्ञात TextView बाध्य कर सकते हैं:

@Bind(R.id.title) CheckBox title; 

प्रश्न: तो कैसे पुस्तकालय काम करता है?

ए: खैर IllegalStateException को कभी नहीं बुलाया जाता है और आपके पास क्लासकास्ट अपवाद है। ऐसा क्यों है कि मैं वास्तव में निश्चित नहीं हूं। हालांकि, बटरकेनिफ कोड उत्पन्न करता है, इसका उद्देश्य संकलन त्रुटियों से बचने के लिए किया जा सकता है।

उदाहरण के लिए

:

public interface Some { 
} 

public static void weWantSome(Some d) { 
} 

public static void test() { 
    String o = "test"; 
    weWantSome((Some)o); //<-- compile error 
    weWantSome(Main.<Some>cast(o)); //<-- runtime error 
} 

इसीलिए पिछले उदाहरण कोड में संकलित लेकिन नहीं चलता है।

7

जेनरिक्स प्रकार केवल टाइप एरर के कारण संकलन समय पर चेक किए जाते हैं। ऐसा इसलिए किया जाता है क्योंकि पिछली संगतता को तोड़ने और सभी मौजूदा पुस्तकालयों को पुन: संकलित करने के लिए मजबूर किए बिना जावा 5 में रनटाइम में जेनेरिक को पेश करने का कोई तरीका नहीं था।

जब आप "जेनेरिक" वर्ग या विधि को परिभाषित करते हैं तो लंबा इतिहास छोटा होता है, वास्तविक कोड को विधि के बाध्यकारी प्रकार के बजाय Object के रूप में संकलित किया जाता है। सभी प्रकार के चेक संकलन समय पर किए जाते हैं।

तो, आपका विधि कोड वास्तव में return कथन में एक कलाकार नहीं कर रहा है, क्योंकि यह Object वापसी मूल्य पर कुछ (String) असाइन कर रहा है। वास्तविक क्लासकास्ट अपवाद कॉलिंग लाइन द्वारा वापस किया जाता है क्योंकि यह वह जगह है जब संदर्भ चर वास्तव में टाइप किया जाता है।

+0

यहां किसी और ने बिल्कुल ऐसा करने की कोशिश की: http://stackoverflow.com/questions/14524751/cast-object-to-generic-type-for-returning – SJuan76

+0

लाइब्रेरी तब कैसे काम करती है? – Greyshack

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