2008-10-28 9 views
12

कुछ कोड मैं निम्नलिखित कोडमुझे क्लास के जावा 5 विधि कास्ट कब उपयोग करना चाहिए?

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 

और मैं अगर इस तरह से कास्टिंग

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto); 

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

+0

यह भी देखें http://stackoverflow.com/questions/7900410/why-would-i-use-java-lang-class-cast/7902048#7902048 – irreputable

उत्तर

20

ये कथन समान नहीं हैं। कास्ट विधि एक सामान्य विधि आमंत्रण (invokevirtual जेवीएम निर्देश) है जबकि दूसरा भाषा निर्माण (checkcast निर्देश) है। यदि आप ऊपर दिखाते हैं, तो आपको दूसरे फॉर्म का उपयोग करना चाहिए: (TrTuDocPackTypeDto) packDto

cast विधि जेनेरिक के साथ प्रतिबिंबित प्रोग्रामिंग में उपयोग की जाती है, जब आपके पास कुछ चर प्रकार के लिए क्लास इंस्टेंस होता है। आप इसे इस तरह इस्तेमाल कर सकते हैं:

/* DO NOT DO THIS! */ 
List raw = new ArrayList(); 
... 
return (List<Widget>) raw; 

संकलक, आपको चेतावनी देगा Unchecked cast from List to List<Widget>:

public <T> Set<T> find(Class<T> clz, Filter criteria) { 
    List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */ 
    Set<T> safe = new HashSet<T>(); 
    for (Object o : raw) 
    safe.add(clz.cast(o)); 
    return safe; 
} 

यह आपको एक सुरक्षित तरीका बस एक सामान्य प्रकार के लिए एक कच्चे प्रकार कास्टिंग की गलत विकल्प से बचने के लिए देता है , जिसका अर्थ है कि इलिप्सिस में, कोई कच्चे सूची में Gadget जोड़ सकता था, जो अंततः ClassCastException का कारण बनता है जब कॉलर Widget उदाहरणों की लौटाई गई सूची पर पुनरावृत्त करता है।

+0

भाषा संदर्भ के त्वरित स्कैन पर, ऐसा लगता है कि 'class.cast()' संकलक सामान्य रूप से प्रदर्शित होने वाली 'असुरक्षित रूपांतरण' चेतावनी को बाईपास करेगा। एरिक्सन ने कहा, जब तक आप नहीं कर सकते तब तक भाषा निर्माण का उपयोग करें। ;-) –

+0

क्या आप समझा सकते हैं कि आपको दूसरे मामले में क्या करना चाहिए? मैं कल इस कंपाइलर चेतावनी में भाग गया लेकिन इसे नजरअंदाज कर दिया क्योंकि मैं आलसी हूं। क्या आप सूची .cast (कच्चे) जैसी कुछ सुझा रहे हैं? –

+0

@Outlaw - दूसरे मामले से बचने के लिए, आपको उपरोक्त "ढूंढें" विधि में प्रदान की गई कुछ चीज़ों का उपयोग करने की आवश्यकता है। यही है, आपको 'सूची' पर पुन: प्रयास करने की आवश्यकता है और परीक्षण करें कि प्रत्येक तत्व वास्तव में 'विजेट' है। फिर, आपको "चेतावनी ) कच्चे" से प्राप्त चेतावनी को अनदेखा करना ठीक होगा। – erickson

-3

ये दोनों कथन समान हैं। जो भी आपको अधिक पठनीय लगता है उसे चुनें। दूसरी विधि मेरे अनुभव में अधिक आम है, और यह एक बार है जिसे मैं पसंद करता हूं।

जब मैं प्रतिबिंब के साथ काम कर रहा हूं, तो मैं केवल कास्ट विधि का उपयोग करता हूं, और यह उस स्थिति में अच्छी तरह से पढ़ता है। अन्य सभी बार मैं खुद को कास्टिंग के दूसरे तरीके का उपयोग कर पाता हूं।

4

ऐसा करने के लिए मुख्य मामला (आईएमई) तब होता है जब आपको एक सामान्य वर्ग/विधि में सुरक्षित रूप से डालने की आवश्यकता होती है। मिरर टाइप करने के कारण, आप T पर नहीं डाले जा सकते हैं, लेकिन अगर आपको Class<? extends T> पैरामीटर प्रदान किया गया है तो आप इसे कास्ट करने के लिए उपयोग कर सकते हैं और परिणाम T प्रकार के चर के लिए असाइन किया जा सकता है।

0

मुझे ऐसा उदाहरण नहीं मिल रहा है जहां कास्ट विधि संभव है और कास्ट सिंटैक्स नहीं है। हालांकि, कोड को देखते हुए, ऐसा लगता है कि यदि संभव नहीं है, तो कास्ट विधि क्लासकास्ट अपवाद को बिना किसी प्रकार की जानकारी के फेंक देती है, जबकि कास्ट सिंटैक्स आपको कुछ संकेत देगा (जैसा कि, "स्नूपी को नहीं डाला जा सका TyrannosorusRex ") :

/** 
* Casts an object to the class or interface represented 
* by this <tt>Class</tt> object. 
* 
* @param obj the object to be cast 
* @return the object after casting, or null if obj is null 
* 
* @throws ClassCastException if the object is not 
* null and is not assignable to the type T. 
* 
* @since 1.5 
*/ 
public T cast(Object obj) { 
if (obj != null && !isInstance(obj)) 
    throw new ClassCastException(); 
return (T) obj; 
} 
+0

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

0
प्रथम रूप के साथ

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 

आप यह कर सकते हैं:

public void dynamicCast(Class clazz, Object o) { 
    this.x = clazz.cast(o); 
} 
वें के साथ

ई सेकंड आप नहीं कर सकते हैं। कास्टिंग वर्ग हार्ड कोडित होना चाहिए।

आप पहले स्थान पर कास्ट करने के लिए एक चर का उपयोग क्यों करेंगे? यह एक और सवाल है।:) पहली बात जो दिमाग में आती है वह है, आप उस वर्ग को संकलित करने के समय (संकलित समय पर) नहीं जानते हैं।

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