जावा: मैं एक प्रकार से दूसरे प्रकार के चर की गतिशील कास्टिंग कैसे कर सकता हूं?


85

मैं एक जावा चर के लिए गतिशील कास्टिंग करना चाहूंगा, कास्टिंग प्रकार एक अलग चर में संग्रहीत है।

यह नियमित कास्टिंग है:

 String a = (String) 5;

यह वही चीज है जो मैं चाहता हूं:

 String theType = 'String';
 String a = (theType) 5;

क्या यह संभव है और यदि ऐसा हो तो कैसे? धन्यवाद!

अपडेट करें

मुझे लगता है HashMapकि मैं प्राप्त के साथ एक वर्ग को आबाद करने की कोशिश कर रहा हूँ ।

यह कंस्ट्रक्टर है:

public ConnectParams(HashMap<String,Object> obj) {

    for (Map.Entry<String, Object> entry : obj.entrySet()) {
        try {
            Field f =  this.getClass().getField(entry.getKey());                
            f.set(this, entry.getValue()); /* <= CASTING PROBLEM */
        } catch (NoSuchFieldException ex) {
            log.error("did not find field '" + entry.getKey() + '"');
        } catch (IllegalAccessException ex) {
            log.error(ex.getMessage());         
        }
    }

}

यहाँ समस्या यह है कि कुछ वर्ग के चर प्रकार के होते हैं Double, और यदि संख्या 3 प्राप्त होती है तो इसे Integerइस प्रकार देखता है और मुझे टाइप समस्या है।


इसका कोई मतलब नहीं है। आप चाहते हैं कि चर नाम एक स्ट्रिंग को स्ट्रिंग करने के लिए एक प्रकार हो? क्या?
cletus

3
मुझे जवाब नहीं पता, लेकिन मुझे डर है कि यह रखरखाव नरक बन सकता है ... बस जावा खुद सीख रहा हूं, लेकिन मैं उन स्थितियों से बचूंगा जिनके लिए इस तरह के दृष्टिकोण की आवश्यकता है। मुझे पूरा यकीन है कि आप जो भी करते हैं उसे बेहतर तरीके से लागू किया जा सकता है ... बस मेरे 2 सेंट।
Sejanus

ठीक है मैं अधिक जानकारी प्रदान करूंगा कि मैं क्या हासिल करने की कोशिश कर रहा हूं।
ufk

नीचे अपना जवाब भी अपडेट किया!
user85421

जवाबों:


14

अपने अद्यतन के बारे में, जावा में इस को हल करने के लिए एक ही रास्ता कोड लिखना है कि कवर के बहुत सारे के साथ सभी मामलों ifऔर elseऔर instanceofभाव। आप जो करने की कोशिश करते हैं वह ऐसा लगता है जैसे कि गतिशील भाषाओं के साथ प्रोग्राम करने के लिए उपयोग किया जाता है। स्थिर भाषाओं में, आप जो करने का प्रयास करते हैं वह लगभग असंभव है और आप जो करने का प्रयास करते हैं उसके लिए एक पूरी तरह से अलग दृष्टिकोण का चयन करेंगे। स्थैतिक भाषाएं केवल गतिशील लोगों की तरह लचीली नहीं होती हैं :)

जावा सबसे अच्छा अभ्यास के अच्छे उदाहरण हैं BalusC द्वारा जवाब (यानी ObjectConverter) और Andreas_D द्वारा जवाब (यानी Adapter) के नीचे।


इसका कोई मतलब नहीं है

String a = (theType) 5;

इस प्रकार का aवैधानिक रूप से बाध्य होना Stringइसका कोई अर्थ नहीं है कि इस स्थिर प्रकार का एक गतिशील कलाकारों के लिए कोई मतलब नहीं है।

पुनश्च: आपके उदाहरण की पहली पंक्ति के रूप में लिखा जा सकता है Class<String> stringClass = String.class;लेकिन फिर भी, आप stringClassचर का उपयोग नहीं कर सकते ।


मुझे उम्मीद है कि मैंने जो अपडेट पोस्ट किया है वह बताएगा कि मैं क्या करने की कोशिश कर रहा हूं। मैं एक php बैकग्राउंड से आता हूँ इसलिए शायद यह बात जावा में संभव नहीं है।
ufk

वास्तव में, जावा में आप उस गतिशील नहीं हो सकते, मेरे अपडेट को भी देखें।
आखुण

इस नीचे दिए गए BalusC के देखें जवाब लंबाई (और दर्द), जो करने के लिए आप तय करना है है ...
akuhn

मुझे पता है कि यह देर हो चुकी है, लेकिन मुझे लगता है कि उनका मतलब था [theype] a = (thetype) some_object; जो व्यर्थ है क्योंकि आप सिर्फ ऑब्जेक्ट कर सकते हैं a = some_object फाइन
जॉर्ज जेवियर

120

हाँ यह प्रतिबिंब का उपयोग करना संभव है

Object something = "something";
String theType = "java.lang.String";
Class<?> theClass = Class.forName(theType);
Object obj = theClass.cast(something);

लेकिन इसका कोई मतलब नहीं है क्योंकि परिणामस्वरूप वस्तु को एक Objectप्रकार के चर में बचाया जाना चाहिए । यदि आपको किसी दिए गए वर्ग के चर की आवश्यकता है, तो आप बस उस वर्ग को डाल सकते हैं।

यदि आप किसी दिए गए वर्ग को प्राप्त करना चाहते हैं, Numberउदाहरण के लिए:

Object something = new Integer(123);
String theType = "java.lang.Number";
Class<? extends Number> theClass = Class.forName(theType).asSubclass(Number.class);
Number obj = theClass.cast(something);

लेकिन अभी भी ऐसा करने का कोई मतलब नहीं है, आप बस डाल सकते हैं Number

किसी वस्तु का कास्टिंग कुछ भी नहीं बदलता है; यह उसी तरह है जैसे कंपाइलर इसका इलाज करता है।
ऐसा ही कुछ करने के लिए एकमात्र कारण अगर वस्तु दिए गए वर्ग से या इसके किसी भी उपवर्ग का एक उदाहरण है की जाँच करने के लिए है, लेकिन यह बेहतर उपयोग किया जा होगा instanceofया Class.isInstance()

अपडेट करें

अपने पिछले अनुसार अद्यतन वास्तविक समस्या आप एक है कि है Integerकि आपका HashMapहै कि एक को सौंपा जाना चाहिए Double। इस मामले में आप क्या कर सकते हैं, फ़ील्ड के प्रकार की जाँच करें और के xxxValue()तरीकों का उपयोग करेंNumber

...
Field f =  this.getClass().getField(entry.getKey());
Object value = entry.getValue();
if (Integer.class.isAssignableFrom(f.getType())) {
    value = Integer.valueOf(((Number) entry.getValue()).intValue());
} else if (Double.class.isAssignableFrom(f.getType())) {
    value = Double.valueOf(((Number) entry.getValue()).doubleValue());
} // other cases as needed (Long, Float, ...)
f.set(this, value);
...

(निश्चित नहीं है कि मुझे गलत प्रकार होने का विचार पसंद है Map)


22

आपको इसके लिए क्रमबद्ध लिखना ObjectConverterहोगा। यह उल्लेखनीय है यदि आपके पास वह दोनों वस्तु है जिसे आप परिवर्तित करना चाहते हैं और आप लक्ष्य वर्ग को जानते हैं कि आप किसको परिवर्तित करना चाहते हैं। इस विशेष स्थिति में आप लक्ष्य वर्ग प्राप्त कर सकते हैं Field#getDeclaringClass()

आप यहां इस तरह का एक उदाहरण पा सकते हैं ObjectConverter। यह आपको आधार विचार देना चाहिए। यदि आप अधिक रूपांतरण संभावनाएँ चाहते हैं, तो वांछित तर्क और वापसी प्रकार के साथ इसमें और विधियाँ जोड़ें।


@BalusC - मुझे ObjectConverter कोड दिलचस्प लगता है, क्या आप इसके लिए उपयोग के मामलों का वर्णन कर सकते हैं?
srini.venigalla

यह उन मामलों में उपयोगी है जब कॉन्फ़िगरेशन पर अधिवेशन पसंद किया जाता है और स्रोत प्रकार लक्ष्य प्रकार से मेल नहीं खाता है। मैंने इसे 2-3 साल पहले अपने (शौक के प्रयोजनों के लिए शुद्ध) ORM और MVC चौखटे में इस्तेमाल किया है। ब्लॉग लेख का प्रमुख पाठ भी देखें।
बालुसक

12

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

public class Test {

    public String var1;
    public Integer var2;
}

public class Main {

    public static void main(String[] args) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("var1", "test");
        map.put("var2", 1);

        Test t = new Test();

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Field f = Test.class.getField(entry.getKey());

            f.set(t, f.getType().cast(entry.getValue()));
        }

        System.out.println(t.var1);
        System.out.println(t.var2);
    }
}

1
क्या होगा यदि प्रविष्टि प्रकार फ़ील्ड प्रकार का एक सुपरटेप नहीं है? फिर आपको वास्तव में प्रोग्रामेटिक रूप से कन्वर्ट करने की आवश्यकता होगी।
BalusC

7

आप एक नीचे की तरह एक साधारण कास्टमेथोड लिख सकते हैं।

private <T> T castObject(Class<T> clazz, Object object) {
  return (T) object;
}

अपनी विधि में आपको इसका उपयोग करना चाहिए

public ConnectParams(HashMap<String,Object> object) {

for (Map.Entry<String, Object> entry : object.entrySet()) {
    try {
        Field f =  this.getClass().getField(entry.getKey());                
        f.set(this, castObject(entry.getValue().getClass(), entry.getValue()); /* <= CASTING PROBLEM */
    } catch (NoSuchFieldException ex) {
        log.error("did not find field '" + entry.getKey() + '"');
    } catch (IllegalAccessException ex) {    
        log.error(ex.getMessage());          
    }    
}

}

हां, मुझे लगता है कि यह उत्तर वही है जो पूछने वाला चाहता है। वह / वह सिर्फ एक क्लास <?> प्राप्त करता है, और एक उदाहरण को क्लास में बदलना चाहता है "?"। डिफ़ॉल्ट रूप से जावा इसका समर्थन नहीं करता है। लेकिन <T> का उपयोग करके हम ऐसा कर सकते हैं।
ruiruige1991

@ ruiruige1991 यह गलत है। टी किस मामले में एक सामान्य है। रनटाइम के दौरान जेनरिक कुछ नहीं करते हैं। (ट) ब्लाह सिर्फ एरेस प्रकार के कारण रनटाइम के दौरान (ऑब्जेक्ट) ब्लाह होगा। संक्षेप में, जेनरिक -> संकलन-समय, और रनटाइम के दौरान कोई प्रभाव नहीं पड़ता है। चूंकि गतिशील -> रनटाइम और जेनरिक -> संकलन समय, जेनरिक बेकार हैं।
जॉर्ज जेवियर

5

यह काम करता है और आपके दृष्टिकोण के लिए एक सामान्य पैटर्न भी है: एडाप्टर पैटर्न । लेकिन निश्चित रूप से, (1) यह वस्तुओं के लिए जावा आदिम कास्टिंग के लिए काम नहीं करता है और (2) वर्ग को अनुकूलन योग्य होना चाहिए (आमतौर पर एक कस्टम इंटरफ़ेस लागू करके)।

इस पैटर्न के साथ आप कुछ ऐसा कर सकते हैं:

Wolf bigBadWolf = new Wolf();
Sheep sheep = (Sheep) bigBadWolf.getAdapter(Sheep.class);

और भेड़िया वर्ग में getAdapter विधि:

public Object getAdapter(Class clazz) {
  if (clazz.equals(Sheep.class)) {
    // return a Sheep implementation
    return getWolfDressedAsSheep(this);
  }

  if (clazz.equals(String.class)) {
    // return a String
    return this.getName();
  }

  return null; // not adaptable
}

आपके लिए विशेष विचार - यह असंभव है। आप कास्टिंग के लिए स्ट्रिंग मान का उपयोग नहीं कर सकते।


2

आपकी समस्या "गतिशील कास्टिंग" की कमी नहीं है। कास्टिंग Integerके लिए Doubleबिल्कुल भी संभव नहीं है। आप जावा को एक प्रकार की वस्तु देना चाहते हैं, संभवतः एक असंगत प्रकार का एक क्षेत्र, और क्या यह किसी तरह स्वचालित रूप से पता लगाएगा कि प्रकारों के बीच कैसे परिवर्तित किया जाए।

इस तरह की चीज़ बहुत अच्छे कारणों से जावा, और IMO जैसी जोरदार टाइप की गई भाषा के लिए एक प्रकार का शब्द है।

आप वास्तव में क्या करने की कोशिश कर रहे हैं? परावर्तन के उपयोग से सभी सुंदर दिखते हैं।


@ नाम: आपके द्वारा सुझाए गए संपादन के विषय में: ध्यान दें कि मैं आदिम मूल्यों के बारे में नहीं बल्कि रैपर क्लासेस (कैपिटलाइज़ेशन द्वारा संकेतित और कोड के रूप में स्टाइल) के बारे में बात कर रहा हूं, और उन दोनों के बीच कास्टिंग निश्चित रूप से संभव नहीं है।
माइकल बोर्गवर्ड

1

यह मत करो। इसके बजाय बस एक ठीक से मानकीकृत निर्माता है। कनेक्शन मापदंडों के सेट और प्रकार वैसे भी तय होते हैं, इसलिए यह सब गतिशील रूप से करने का कोई मतलब नहीं है।


1

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

print ++($foo = '99');  # prints '100'
print ++($foo = 'a0');  # prints 'a1'

जावा में, यह बेहतर तरीका है जिसे मैं "क्रॉस-कास्टिंग" कहता हूं। क्रॉस-कास्टिंग के साथ, प्रतिबिंब का उपयोग निर्माणकर्ताओं की एक आलसी-भरी हुई कैश में किया जाता है और विधियाँ जिन्हें निम्नलिखित स्थिर विधि के माध्यम से गतिशील रूप से खोजा जाता है:

Object fromString (String value, Class targetClass)

दुर्भाग्यवश, कोई अंतर्निहित जावा विधियाँ जैसे कि Class.cast () स्ट्रिंग के लिए BigDecimal या String to Integer या कोई अन्य रूपांतरण नहीं होगा जहाँ कोई सहायक वर्ग पदानुक्रम नहीं है। मेरे हिस्से के लिए, यह हासिल करने के लिए पूरी तरह से गतिशील तरीका प्रदान करना है - जिसके लिए मुझे नहीं लगता कि पूर्व संदर्भ सही दृष्टिकोण है - प्रत्येक रूपांतरण को कोड करने के लिए। सीधे शब्दों में कहें, तो कार्यान्वयन केवल कास्ट-से-स्ट्रिंग करने के लिए है यदि यह कानूनी / संभव है।

तो समाधान सरल प्रतिबिंब है या तो सार्वजनिक सदस्यों की तलाश में:

STRING_CLASS_ARRAY = (नया वर्ग [] {String.class});

a) सदस्य सदस्य = targetClass.getMethod (method.getName) (, STRING_CLASS_ARRAY); b) सदस्य सदस्य = targetClass.getConstructor (STRING_CLASS_ARRAY);

आप पाएंगे कि सभी प्राइमेटिव्स (इंटेगर, लॉन्ग आदि) और सभी बेसिक्स (बिगइन्टेगर, बिगडेसिमल, इत्यादि) और यहां तक ​​कि java.regex.Pattern सभी इस दृष्टिकोण से कवर किए गए हैं। मैंने उत्पादन परियोजनाओं पर महत्वपूर्ण सफलता के साथ इसका उपयोग किया है जहां भारी मात्रा में मनमाने ढंग से स्ट्रिंग मूल्य इनपुट हैं जहां कुछ और सख्त जाँच की आवश्यकता थी। इस दृष्टिकोण में, अगर कोई विधि नहीं है या जब विधि का आह्वान किया जाता है तो एक अपवाद को फेंक दिया जाता है (क्योंकि यह एक गैर-संख्यात्मक इनपुट के लिए एक गैर-संख्यात्मक इनपुट है जैसे पैटर्न के लिए), जो चेकिंग को विशिष्ट प्रदान करता है लक्ष्य वर्ग निहित तर्क।

इसके कुछ डाउनसाइड हैं:

1) आपको प्रतिबिंब को अच्छी तरह से समझने की आवश्यकता है (यह थोड़ा जटिल है और नौसिखियों के लिए नहीं)। 2) जावा कक्षाओं में से कुछ और वास्तव में 3-पार्टी पुस्तकालय (आश्चर्य) ठीक से कोडित नहीं हैं। यही है, ऐसे तरीके हैं जो इनपुट के रूप में एकल स्ट्रिंग तर्क लेते हैं और लक्ष्य वर्ग का एक उदाहरण देते हैं लेकिन ऐसा नहीं है जो आप सोचते हैं ... पूर्णांक वर्ग पर विचार करें:

static Integer getInteger(String nm)
      Determines the integer value of the system property with the specified name.

उपरोक्त विधि का वास्तव में इंटिजर्स के साथ कोई लेना-देना नहीं है क्योंकि ऑब्जेक्ट्स आदिम स्याही को लपेटते हैं। प्रतिबिंब इसे एक संभावित उम्मीदवार के रूप में एक स्ट्रिंग से एक पूर्णांक बनाने के लिए गलत तरीके से डिकोड, मान और निर्माता सदस्य के रूप में मिलेगा - जो सभी सबसे मनमाने ढंग से स्ट्रिंग रूपांतरणों के लिए उपयुक्त हैं, जहां वास्तव में आपके इनपुट डेटा पर नियंत्रण नहीं है, लेकिन आप चाहते हैं पता है कि यह एक पूर्णांक संभव है।

इसके बाद के संस्करण में सुधार करने के लिए, तरीकों कि अपवाद फेंक की तलाश में एक अच्छी शुरुआत है, क्योंकि अमान्य इनपुट मूल्यों है कि इस तरह की वस्तुओं के उदाहरण बना होना चाहिए अपवाद फेंक देना । दुर्भाग्य से, कार्यान्वयन अलग-अलग होते हैं चाहे अपवाद घोषित किए गए हों या नहीं। Integer.valueOf (स्ट्रिंग) उदाहरण के लिए एक चेक किए गए नंबरफ़ॉर्मैट अपवाद को फेंकता है, लेकिन प्रतिबिंब देखने के दौरान Pattern.compile () अपवाद नहीं पाए जाते हैं। फिर से, इस गतिशील "क्रॉस-कास्टिंग" दृष्टिकोण का विफल होना मुझे लगता है कि ऑब्जेक्ट निर्माण विधियों में अपवाद घोषणाओं के लिए एक बहुत ही गैर-मानक कार्यान्वयन है।

अगर किसी को यह अधिक जानकारी चाहिए कि ऊपर कैसे लागू किया गया था, तो मुझे बताएं लेकिन मुझे लगता है कि यह समाधान अधिक लचीला / एक्स्टेंसिबल है और कम कोड के बिना टाइप-सेफ्टी के अच्छे हिस्सों को खो देता है। बेशक "अपने डेटा को जानना" हमेशा सबसे अच्छा होता है, लेकिन जैसा कि हम में से कई लोग पाते हैं, हम कभी-कभी केवल अप्रबंधित सामग्री के प्राप्तकर्ता होते हैं और हमें इसका सही उपयोग करने के लिए सबसे अच्छा करना पड़ता है।

चीयर्स।


1

तो, यह एक पुरानी पोस्ट है, हालांकि मुझे लगता है कि मैं इसमें कुछ योगदान कर सकता हूं।

आप हमेशा कुछ ऐसा कर सकते हैं:

package com.dyna.test;  

import java.io.File;  
import java.lang.reflect.Constructor;  

public class DynamicClass{  

  @SuppressWarnings("unchecked")  
  public Object castDynamicClass(String className, String value){  
    Class<?> dynamicClass;  

    try  
    {  
      //We get the actual .class object associated with the specified name  
      dynamicClass = Class.forName(className);  



    /* We get the constructor that received only 
     a String as a parameter, since the value to be used is a String, but we could
easily change this to be "dynamic" as well, getting the Constructor signature from
the same datasource we get the values from */ 


      Constructor<?> cons =  
        (Constructor<?>) dynamicClass.getConstructor(new Class<?>[]{String.class});  

      /*We generate our object, without knowing until runtime 
 what type it will be, and we place it in an Object as 
 any Java object extends the Object class) */  
      Object object = (Object) cons.newInstance(new Object[]{value});  

      return object;  
    }  
    catch (Exception e)  
    {  
      e.printStackTrace();  
    }  
    return null;  
  }  

  public static void main(String[] args)  
  {   
    DynamicClass dynaClass = new DynamicClass();  

    /* 
 We specify the type of class that should be used to represent 
 the value "3.0", in this case a Double. Both these parameters 
 you can get from a file, or a network stream for example. */  
    System.out.println(dynaClass.castDynamicClass("java.lang.Double", "3.0"));  

    /* 
We specify a different value and type, and it will work as 
 expected, printing 3.0 in the above case and the test path in the one below, as the Double.toString() and 
 File.toString() would do. */  
    System.out.println(dynaClass.castDynamicClass("java.io.File", "C:\\testpath"));  
  }  

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

इस तरह, आप उन मामलों के लिए जिम्मेदार हो सकते हैं, और कुछ हद तक "गतिशील" कास्टिंग-ऑन-द-फ्लाई बना सकते हैं।

आशा है कि यह किसी को भी मदद करता है क्योंकि यह Google खोजों में बदल रहा है।


0

मुझे हाल ही में ऐसा लगा कि मुझे भी ऐसा करना था, लेकिन फिर एक और तरीका मिला, जो संभवत: मेरे कोड को नॉटी बनाता है, और बेहतर OOP का उपयोग करता है।

मेरे पास कई सहोदर वर्ग हैं जो प्रत्येक एक निश्चित पद्धति को लागू करते हैं doSomething()। उस पद्धति तक पहुँचने के लिए, मुझे पहले उस वर्ग का उदाहरण देना होगा, लेकिन मैंने अपने सभी सहोदर वर्गों के लिए एक सुपरक्लास बनाया और अब मैं सुपरक्लास से इस विधि तक पहुँच बना सकता हूँ।

नीचे मैं "डायनेमिक कास्टिंग" के दो तरीके वैकल्पिक तरीके दिखाता हूं।

// Method 1.
mFragment = getFragmentManager().findFragmentByTag(MyHelper.getName(mUnitNum));
switch (mUnitNum) {
case 0:
    ((MyFragment0) mFragment).sortNames(sortOptionNum);
    break;
case 1:
    ((MyFragment1) mFragment).sortNames(sortOptionNum);
    break;
case 2:
    ((MyFragment2) mFragment).sortNames(sortOptionNum);
    break;
}

और मेरी वर्तमान में इस्तेमाल की गई विधि,

// Method 2.
mSuperFragment = (MySuperFragment) getFragmentManager().findFragmentByTag(MyHelper.getName(mUnitNum));
mSuperFragment.sortNames(sortOptionNum);

आपको कभी गतिशील रूप से कास्ट करने की आवश्यकता नहीं है। विधि doSomething () और उपवर्ग जो पद्धति doSomething () को लागू करने वाले उपवर्ग के साथ होने का आपका सूत्र OOP, बहुरूपता के मुख्य उद्देश्यों में से एक है। ऑब्जेक्ट फू = नया इंटेगर ("1"); foo.toString () रिटर्न 1. भले ही इसे ऑब्जेक्ट को सौंपा गया हो, यह एक इंटेगर है, और इसलिए ऐसा व्यवहार करता है। विधि को आगे बढ़ाने के लिए चल रहे पूर्णांक कार्यान्वयन को चलाएगा। बहुरूपता।
जॉर्ज जेवियर

0

बस मैंने सोचा था कि मैं कुछ ऐसा पोस्ट करूंगा जो मुझे काफी उपयोगी लगे और जो किसी के लिए समान आवश्यकताओं का अनुभव हो सकता है।

निम्नलिखित विधि एक विधि थी जिसे मैंने अपने JavaFX एप्लिकेशन के लिए लिखा था ताकि वह बता सके कि हर बार कंट्रोलर के वापस आने के बाद ऑब्जेक्ट b स्टेटमेंट्स का ऑब्जेक्ट x उदाहरण लिखने से बचें।

public <U> Optional<U> getController(Class<U> castKlazz){
    try {
        return Optional.of(fxmlLoader.<U>getController());
    }catch (Exception e){
        e.printStackTrace();
    }
    return Optional.empty();
}

नियंत्रक प्राप्त करने के लिए विधि घोषणा थी

public <T> T getController()

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

यह वही है जो विधि के लिए अंतिम कॉल की तरह दिखता है (यदि वैकल्पिक वस्तु की मौजूदगी एक उपभोक्ता लेता है

getController(LoadController.class).ifPresent(controller->controller.onNotifyComplete());

0

डायनामिक कास्टिंग के लिए यह प्रयास करें। यह काम करेगा!!!

    String something = "1234";
    String theType = "java.lang.Integer";
    Class<?> theClass = Class.forName(theType);
    Constructor<?> cons = theClass.getConstructor(String.class);
    Object ob =  cons.newInstance(something);
    System.out.println(ob.equals(1234));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.