2009-03-11 23 views
6

मैं Object तर्क के रूप में एक विधि को कार्यान्वित करना चाहता हूं, इसे मनमाने ढंग से टाइप करता है, और यदि यह null रिटर्न में विफल रहता है। यहाँ मैं अब तक है:जावा जेनरिक

public static void main(String[] args) { 
    MyClass a, b; 
    a = Main.<MyClass>staticCast(new String("B")); 
} 

public static class MyClass { 
} 

public static <T> T staticCast(Object arg) { 
    try { 
     if (arg == null) return null; 
     T result = (T) arg; 
     return result; 
    } catch (Throwable e) { 
     return null; 
    } 
} 

दुर्भाग्य वर्ग डाली अपवाद कभी नहीं फेंक दिया जाता है/staticCast() समारोह के मुख्य भाग में पकड़ लिया। ऐसा लगता है कि जावा कंपाइलर फ़ंक्शन String staticCast(Object arg) उत्पन्न करता है जिसमें आपके पास String result = (String) arg; लाइन है, भले ही मैं स्पष्ट रूप से कहूं कि टेम्पलेट प्रकार MyClass होना चाहिए। कोई मदद? धन्यवाद।

+0

वैसे, आपको पकड़ना चाहिए जी केवल क्लासकास्ट अपवाद, फेंकने योग्य नहीं। पकड़ने योग्य गंभीर समस्याएं पैदा कर सकती हैं। –

उत्तर

10

क्योंकि सामान्य प्रकार की जानकारी क्रम में मिटा दिया जाता है, मानक तरीका एक सामान्य प्रकार के कास्ट करने के लिए एक Class वस्तु के साथ है

a = Main.staticCast("B", MyClass.class); 
+0

अधिक प्रत्यक्ष होगा। –

+0

हम्म, क्लैज? क्या यह एक क्लास की तरह है? –

+0

isInstance केवल तभी काम करेगा यदि ऑब्जेक्ट क्लैज का एक उदाहरण है, न कि यह क्लैज का उप-वर्ग है। isAssignableFrom किसी भी चीज पर काम करेगा जो क्लैज, यहां तक ​​कि उप-वर्गों के लिए जा सकता है। –

6

आप जो भी चाहते हैं वह नहीं कर सकते ... कम से कम इस तरह से नहीं। कंपाइलर ने सारी जानकारी हटा दी ताकि आप (टी) कास्ट ऑब्जेक्ट में ऑब्जेक्ट कर सकें - और यह काम करता है।

समस्या यह है कि बाद में आप MyClass = (स्ट्रिंग) ऑब्जेक्ट कर रहे हैं; और इसकी अनुमति नहीं है।

आपने कंपेलरों की जांच को छोड़ दिया है और इसे रनटाइम पर विफल कर दिया है।

तो यह वास्तव में क्या है कि आप ऐसा करने की कोशिश कर रहे हैं? यदि आप हमें बताते हैं कि आप ऐसा क्यों करना चाहते हैं तो हम शायद आपको ऐसा करने का जावा तरीका बता सकते हैं।

अपनी टिप्पणी आप की तरह कुछ कोशिश कर सकते हैं को देखते हुए: सी ++ टेम्पलेट्स के लिए जावा जेनरिक गलती न करें कि

public class Main 
{ 
    public static void main(String[] args) 
    { 
     String a; 
     MyClass b; 
     a = staticCast(new String("B"), String.class); 
     b = staticCast(new String("B"), MyClass.class); 
     System.out.println(a); 
    } 

    public static class MyClass 
    { 
    } 

    public static <T> T staticCast(Object arg, final Class clazz) 
    { 
     // edit - oops forgot to deal with null... 
     if(arg == null) 
     { 
      return (null); 
     } 

     // the call to Class.cast, as mmeyer did, might be better... probably is better... 
     if(arg.getClass() != clazz) 
     { 
      // Given your answer to Ben S... 
      return (null); 

      // throw new ClassCastException("cannot cast a " + arg.getClass() + " to a " + clazz); 
     } 

     return ((T)arg); 
    } 
} 
+0

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

+0

संपादन में प्रदान किए गए कोड को आप जो करना चाहते हैं उसे करना चाहिए – TofuBeer

1

public static void main(String[] args) { 
    MyClass a, b; 
    a = (MyClass)Main.staticCast(new String("B"), MyClass.class); 
} 

public static class MyClass { 
} 

public static staticCast(Object arg, Class class) { 
     if (arg != null && class.isAssignableFrom(arg)) 
      return arg; 
     return null; 
} 

या किसी अन्य से चोरी: वहाँ केवल एक टी के लिए एक staticCast विधि है कि विभिन्न प्रकार के विलोपन के साथ कहा जाता है, नहीं एक होने जा रहा है

बिल्कुल जेनेरिक्स का उपयोग नहीं, मैं इसे इस तरह से लिखते थे का जवाब, जेनरिक का उपयोग कर:

public static <T> T staticCast(Object arg, Class<T> class) { 
     if (arg != null && class.isAssignableFrom(arg)) 
     { 
      T result = class.cast(arg); 
      return result; 
     } 
     return null; 
} 
+0

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

+0

क्या आप विस्तारित कर सकते हैं कि क्यों जावा कंपाइलर MyClass staticCast (ऑब्जेक्ट Arg) उत्पन्न नहीं करता है; जब मैं लाइन में टाइप टी को स्पष्ट रूप से निर्दिष्ट करता हूं: ए = मुख्य। स्टेटिककास्ट (नया स्ट्रिंग ("बी")); मैंने स्पष्ट रूप से इसे बताया ... मैंने सोचा कुछ पढ़ने के लिए एक लिंक बहुत अच्छा होगा। – Budric

+0

@ बुड्रिक: http://java.sun.com/docs/books/tutorial/java/generics/erasure.html आज़माएं। इसके अलावा, [जावा] [जेनेरिक] टैग किए गए प्रश्नों की खोज करें। चारों ओर कुछ सुंदर दिलचस्प हैं। –

4

आप Class<T>.cast(Object obj) की तरह मतलब है?

कुछ की तरह:

Class.forName("YourClass").cast(obj); 

काफी तुम क्या चाहते हो जाना चाहिए।

ध्यान रखें कि यह काफी सुगंधित है और शायद खराब डिजाइन का संकेत है। तब

public static <T> T staticCast(Object arg, Class<T> clazz) { 
    if (arg == null) return null; 
    if (!clazz.isInstance(arg)) 
     return null; 
    T result = clazz.cast(arg); 
    return result; 
} 

इसे इस तरह कहते हैं:

+0

धन्यवाद। समस्या यह है कि यह विफल होने पर वर्ग कास्ट अपवाद फेंक देगा। यह कोड के समान है: (YourClass) ऑब्जेक्ट और आपको त्रुटि पर फेंक दिया गया अपवाद मिलता है जिसे आप कोड की उस पंक्ति का उपयोग करते समय हर बार जांचना चाहते हैं। मैं उस अपवाद को कास्ट() विधि के अंदर पकड़ना और छिपाना चाहता हूं। – Budric

+0

क्या आप चाहते हैं कि सबक्लबस या getConstructor()। NewInstance()। Cast? Class.isInstance का उपयोग कर –

1

मैं सहमत हूं बेन के साथ, हालांकि, मैं निम्नलिखित नोटेशन पसंद करता हूं:

MyClass.class.cast(obj); 
संबंधित मुद्दे