জাভা: আমি কীভাবে এক ধরণের থেকে অন্য ধরণের ভেরিয়েবলের গতিশীল কাস্টিং করতে পারি?


85

আমি জাভা ভেরিয়েবলের জন্য ডায়নামিক ingালাই করতে চাই, ingালাই টাইপটি একটি ভিন্ন ভেরিয়েবলে সঞ্চিত।

এটি নিয়মিত ingালাই:

 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এবং আমার টাইপ সমস্যা রয়েছে।


এটা কোন মানে না। আপনি চান যে ভেরিয়েবলের নামটি স্ট্রিংয়ের জন্য একটি স্ট্রিং toালতে টাইপ হতে পারে? কি?
ক্লিটাস

4
আমি কোনও উত্তর জানি না তবে আমি ভয় করি যে এটি রক্ষণাবেক্ষণের জাহান্নামে পরিণত হতে পারে ... নিজে নিজে জাভা শিখছি তবে আমি এমন পরিস্থিতি এড়াতে চাই যার জন্য এই জাতীয় পদ্ধতির প্রয়োজন হয়। আমি নিশ্চিত যে আপনি যা কিছু করেন তা আরও ভাল উপায়ে প্রয়োগ করা যায় ... কেবল আমার 2 সেন্ট।
সেজানুস

ঠিক আছে আমি কী অর্জন করতে চাইছি তার আরও তথ্য সরবরাহ করব।
ufk

নীচে আমার উত্তর আপডেট!
ব্যবহারকারী 85421

উত্তর:


14

আপনার আপডেট সংক্রান্ত, জাভা এই সমস্যা সমাধানের একমাত্র উপায় লেখ কোডটি প্রচুর সঙ্গে সব ক্ষেত্রে কভার হয় ifএবং elseএবংinstanceof এক্সপ্রেশন। আপনি যা করার চেষ্টা করছেন তা দেখে মনে হচ্ছে গতিময় ভাষা নিয়ে প্রোগ্রাম করার জন্য ব্যবহৃত হয়। স্থির ভাষায়, আপনি যা করার চেষ্টা করছেন তা প্রায় অসম্ভব এবং আপনি যা করার চেষ্টা করছেন তার জন্য সম্ভবত একটি সম্পূর্ণ ভিন্ন পদ্ধতি বেছে নিতে পারে। স্থির ভাষা গতিশীলগুলির মতো তত নমনীয় নয় :)

জাভা সেরা অনুশীলনের ভাল উদাহরণ BalusC দ্বারা উত্তর (অর্থাত ObjectConverter) এবং Andreas_D দ্বারা উত্তর (অর্থাত Adapter) থেকে কম।


এটা কোন মানে নেই

String a = (theType) 5;

ধরণের a স্থিতিশীলভাবে আবদ্ধ হতে পারে Stringতাই এই স্থিতিশীল ধরণের একটি গতিশীল কাস্ট থাকার কোনও মানে হয় না।

PS: আপনার উদাহরণের প্রথম লাইনটি সেই হিসাবে লেখা যেতে পারে Class<String> stringClass = String.class;তবে এখনও আপনি stringClassভেরিয়েবল castালতে ব্যবহার করতে পারবেন না ।


আমি আশা করি যে আপডেট হওয়া পোস্টটি আমি কী করার চেষ্টা করছি তা ব্যাখ্যা করবে। আমি পিএইচপি ব্যাকগ্রাউন্ড থেকে এসেছি তাই সম্ভবত জাভাতে এই জিনিসটি অর্জন করা সম্ভব নয়।
ufk

ঠিক যেমন জাভাতে আপনি সেই গতিশীল হতে পারবেন না, আমার আপডেটটিও দেখুন।
akuhn

নীচে বালাসসির উত্তর দেখুন, এটি আপনাকে যে দৈর্ঘ্যটি (এবং ব্যথা) যেতে হবে ...
akkhn

আমি জানি এটি দেরি হয়ে গেছে তবে আমি মনে করি তিনি [থাইপ] এ = (টাইপ) কিছু_বজেক্ট; যা অর্থহীন কারণ আপনি কেবল একটি = কিছু_জেক্ট জরিমানা করতে পারেন
জর্জ জ্যাভিয়ার

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। এটি আপনাকে বেস ধারণা দিতে হবে। আপনি যদি আরও রূপান্তর সম্ভাবনা চান তবে কেবল এটির জন্য পছন্দসই যুক্তি এবং রিটার্নের ধরণ যুক্ত করুন।


@ বালুসসি - আমি অবজেক্টকভারটার কোডটি আকর্ষণীয় মনে করি, আপনি কি দয়া করে এর ব্যবহারের ক্ষেত্রে বর্ণনা দিতে পারেন?
srini.venigalla

কনফিগারেশন ওভার কনফিগারেশন পছন্দ করা হয় এবং উত্স টাইপ লক্ষ্য প্রকারের সাথে মেলে না এমন ক্ষেত্রে এটি কার্যকর হয়। আমি আমার (শখের উদ্দেশ্যে খাঁটি) ওআরএম এবং এমভিসি ফ্রেমওয়ার্কগুলিতে এটি 2-3 বছর আগে ব্যবহার করেছি। এছাড়াও ব্লগ নিবন্ধের শীর্ষস্থানীয় পাঠ্য দেখুন।
বালাসসি

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);
    }
}

4
যদি প্রবেশের ধরণটি ক্ষেত্রের টাইপের মোটামুটি সুপার টাইপ না হয় তবে কী হবে? এরপরে আপনাকে অবশ্যই প্রোগ্রামালিমে রূপান্তর করতে হবে।
বালুসসি

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

এটি কাজ করে এবং আপনার পদ্ধতির জন্য এমনকি একটি সাধারণ প্যাটার্ন রয়েছে: অ্যাডাপ্টার প্যাটার্ন । তবে অবশ্যই (১) এটি জাভা আদিম বস্তুগুলিতে ingালাইয়ের জন্য কাজ করে না এবং (২) শ্রেণিটি মানিয়ে নিতে হবে (সাধারণত একটি কাস্টম ইন্টারফেস প্রয়োগ করে)।

এই নিদর্শন দিয়ে আপনি যেমন কিছু করতে পারেন:

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
}

আপনার জন্য বিশেষ ধারণা - এটি অসম্ভব। Castালাইয়ের জন্য আপনি স্ট্রিং মান ব্যবহার করতে পারবেন না।


2

আপনার সমস্যা "গতিশীল castালাই" এর অভাব নয়। কাস্ট Integerকরা Doubleমোটেই সম্ভব নয়। আপনি জাভাটিকে এক প্রকারের একটি বস্তু, একটি সম্ভবত বেমানান ধরণের ক্ষেত্র উপহার দিতে চান বলে মনে হয় এবং কীভাবে প্রকারের মধ্যে রূপান্তর করতে হয় তা কোনওভাবে স্বয়ংক্রিয়ভাবে এটি নির্ধারণ করতে চাই।

এই জাতীয় জিনিসটি খুব ভাল কারণে জাভা এবং আইএমওর মতো দৃ strongly়ভাবে টাইপিত ভাষার কাছে অ্যানথেমা।

আপনি আসলে কী করার চেষ্টা করছেন? প্রতিফলন ব্যবহারের সবগুলি দেখতে বেশ মশলাদার দেখাচ্ছে।


@ নাম: আপনি যে সম্পাদনাটি পরামর্শ দিচ্ছেন সে সম্পর্কে: নোট করুন যে আমি আদিম মানগুলি নিয়ে নয় তবে মোড়কের ক্লাসগুলি (মূলধন এবং কোড হিসাবে স্টাইলিং দ্বারা স্বাক্ষরিত) সম্পর্কে কথা বলছি এবং সেগুলির মধ্যে ভোটদান অবশ্যই সম্ভব নয়।
মাইকেল বর্গওয়ার্ট

1

এটি করবেন না। পরিবর্তে একটি সঠিকভাবে প্যারামিটারাইজড কনস্ট্রাক্টর রাখুন। সংযোগের পরামিতিগুলির সেট এবং প্রকারগুলি যাইহোক ঠিক করা হয়েছে, তাই এগুলি সমস্ত গতিশীলভাবে করার কোনও মানে নেই।


1

এটির মূল্যের জন্য, বেশিরভাগ স্ক্রিপ্টিং ভাষা (পার্লের মতো) এবং নন-স্ট্যাটিক কমপাইল-টাইম ল্যাঙ্গুয়েজগুলি (পিকের মতো) স্বয়ংক্রিয় রান-টাইম ডায়নামিক স্ট্রিংকে (তুলনামূলক স্বেচ্ছাচারী) অবজেক্ট রূপান্তরকে সমর্থন করে। প্রকার-সুরক্ষা না হারিয়ে জাভাতেও এটি সম্পন্ন করা যায় এবং স্ট্যাটিকালি-টাইপ করা ভাল স্টাফগুলি গতিশীল castালাইয়ের সাথে মন্দ কাজ করে এমন কিছু ভাষায় খারাপ কাজ করে। পার্ল উদাহরণ যা কিছু প্রশ্নবিদ্ধ গণিত করে:

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

জাভাতে, আমি "ক্রস-কাস্টিং" বলি এমন একটি পদ্ধতি ব্যবহার করে এটি আরও ভাল (আইএমএইচও) সফল হয়। ক্রস-ingালাইয়ের সাথে, প্রতিচ্ছবিটি নির্মাণকারী এবং পদ্ধতিগুলির অলস-বোঝা ক্যাশে ব্যবহৃত হয় যা নিম্নলিখিত স্থিতিক পদ্ধতির মাধ্যমে গতিশীলভাবে আবিষ্কার করা হয়:

Object fromString (String value, Class targetClass)

দুর্ভাগ্যক্রমে, ক্লাস.কাস্টের মতো কোনও অন্তর্নিহিত জাভা পদ্ধতিগুলি স্ট্রিং টু বিগডিসিমাল বা স্ট্রিং টু ইন্টিজার বা অন্য কোনও রূপান্তরের জন্য এটি করবে না যেখানে সমর্থনমূলক শ্রেণিবদ্ধতা নেই। আমার অংশ হিসাবে, বিষয়টি হ'ল এটি অর্জনের জন্য একটি সম্পূর্ণ গতিশীল উপায় প্রদান করা - যার জন্য আমি মনে করি না যে পূর্ববর্তী রেফারেন্সটি সঠিক পদ্ধতির - প্রতিটি রূপান্তরকে কোড করার জন্য। সরল কথায় বলতে গেলে, বাস্তবায়নটি যদি আইনী / সম্ভব হয় তবে কেবল স্ট্রিং-থেকে-কাস্ট করতে হবে।

সমাধানটি হ'ল সরল প্রতিচ্ছবি হ'ল জনসাধারণের সদস্যদের সন্ধান করা:

STRING_CLASS_ARRAY = (নতুন শ্রেণি [] ring স্ট্রিং.ক্লাস});

ক) সদস্য সদস্য = টার্গেটক্লাস.সেটমথোড (মেথড.জেটনেম (), STRING_CLASS_ARRAY); খ) সদস্য সদস্য = targetClass.getConstructor (STRING_CLASS_ARRAY);

আপনি দেখতে পাবেন যে সমস্ত আদিম (পূর্ণসংখ্যা, লং, ইত্যাদি) এবং সমস্ত বেসিক (বিগইন্টিজার, বিগডিসিমাল, ইত্যাদি) এবং এমনকি java.regex.Pattern সমস্ত এই পদ্ধতির মাধ্যমে আবৃত। আমি এগুলি উত্পাদন প্রকল্পগুলিতে উল্লেখযোগ্য সাফল্যের সাথে ব্যবহার করেছি যেখানে প্রচুর পরিমাণে স্বেচ্ছাচারী স্ট্রিংয়ের মান রয়েছে যেখানে আরও কিছু কঠোর চেকিংয়ের প্রয়োজন ছিল। এই পদ্ধতির মধ্যে, যদি কোনও পদ্ধতি না থাকে বা পদ্ধতিটি আহ্বান করা হয় তখন একটি ব্যতিক্রম ছুঁড়ে দেওয়া হয় (কারণ এটি একটি অবৈধ মান যেমন একটি বিগডিসিমাল বা কোনও প্যাটার্নের জন্য অবৈধ RegEx এর একটি অ-সংখ্যাসূচক ইনপুট), যা নির্দিষ্ট করে চেক সরবরাহ করে লক্ষ্য শ্রেণীর সহজাত যুক্তি।

এর কিছুটা চলাচল রয়েছে:

1) আপনার প্রতিবিম্বটি ভালভাবে বুঝতে হবে (এটি কিছুটা জটিল এবং নবাগতদের জন্য নয়)। 2) জাভা কিছু ক্লাস এবং প্রকৃতপক্ষে তৃতীয় পক্ষের লাইব্রেরিগুলি (আশ্চর্য) সঠিকভাবে কোড করা হয়নি। এটি হ'ল এমন পদ্ধতি রয়েছে যা ইনপুট হিসাবে একক স্ট্রিং আর্গুমেন্ট গ্রহণ করে এবং লক্ষ্য শ্রেণীর একটি উদাহরণ দেয় তবে আপনি যা ভাবেন তা নয় ... পূর্ণসংখ্যা শ্রেণি বিবেচনা করুন:

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

উপরোক্ত পদ্ধতির আদিম কালিগুলিকে মোড়ানো বস্তু হিসাবে পূর্ণসংখ্যার সাথে আসলে কোনও সম্পর্ক নেই। প্রতিচ্ছবিটি ড্রিংড, মান এবং কনস্ট্রাক্টর সদস্যদের থেকে ভুলভাবে স্ট্রিং থেকে পূর্ণসংখ্যার তৈরির সম্ভাব্য প্রার্থী হিসাবে এটি খুঁজে পাবেন - যা বেশিরভাগ স্বেচ্ছাচারী স্ট্রিং রূপান্তরগুলির জন্য উপযুক্ত যেখানে আপনার ইনপুট ডেটার উপরে সত্যই নিয়ন্ত্রণ নেই তবে কেবল চান এটি একটি পূর্ণসংখ্যা সম্ভব কিনা তা জানুন।

উপরের প্রতিকারের জন্য, ব্যতিক্রমগুলি ছুঁড়ে দেওয়ার পদ্ধতিগুলির সন্ধান করা একটি ভাল শুরু কারণ অবৈধ ইনপুট মানগুলি যা এই জাতীয় সামগ্রীর উদাহরণ তৈরি করে তার ব্যতিক্রম ছুঁড়ে ফেলা উচিত । দুর্ভাগ্যক্রমে, বাস্তবায়নগুলি ব্যতিক্রমগুলি চেক হিসাবে ঘোষিত হয়েছে কিনা তা পৃথক রয়েছে। Integer.valueOf (স্ট্রিং) উদাহরণস্বরূপ একটি চেক করা নম্বর ফরমেট এক্সেক্সশনটি ছুড়ে ফেলে তবে প্যাটার্ন ডটকমপিলে () ব্যতিক্রমগুলি প্রতিচ্ছবি অনুসন্ধানের সময় খুঁজে পাওয়া যায় না। আবার এই গতিশীল "ক্রস-কাস্টিং" পদ্ধতির ব্যর্থতা নয়, আমি অবজেক্ট তৈরির পদ্ধতিতে ব্যতিক্রমী ঘোষণার জন্য খুব মানহীন বাস্তবায়ন বলে মনে করি।

যদি কেউ উপরোক্ত কীভাবে প্রয়োগ করা হয়েছে সে সম্পর্কে আরও বিশদ জানতে চান তবে আমাকে জানান তবে আমি মনে করি যে এই সমাধানটি আরও বেশি নমনীয় / এক্সটেনসিবল এবং টাইপ-সুরক্ষার ভাল অংশগুলি না হারিয়ে কম কোড সহ। অবশ্যই "আপনার ডেটা জানা" সর্বদা সেরা তবে আমাদের মধ্যে অনেকেই খুঁজে পান, আমরা মাঝে মাঝে কেবল পরিচালনা না করে নেওয়া সামগ্রী পেয়েছি এবং এটি সঠিকভাবে ব্যবহারের জন্য আমাদের সেরাটি করতে হবে।

চিয়ার্স


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"));  
  }  

অবশ্যই এটি অন্যান্য গানের মতো (যেমন পাইথন) আসলে গতিশীল castালাই নয়, কারণ জাভা একটি স্ট্যাটিকালি টাইপড ল্যাং। যাইহোক, এটি এমন কয়েকটি সীমাবদ্ধ সমস্যার সমাধান করতে পারে যেখানে আপনাকে কিছু শনাক্তকারীর উপর নির্ভর করে আপনাকে বিভিন্ন উপায়ে কিছু ডেটা লোড করতে হবে। এছাড়াও, স্ট্রিং প্যারামিটারের সাথে আপনি যে অংশটি কনস্ট্রাক্টর পাবেন সে অংশটি একই তথ্য উত্স থেকে প্যারামিটারটি পাস করার পরে সম্ভবত আরও নমনীয় করা যেতে পারে। অর্থাত্ একটি ফাইল থেকে, আপনি যে কনস্ট্রাক্টর স্বাক্ষরটি ব্যবহার করতে চান তা পেয়েছেন এবং মানগুলির তালিকা ব্যবহার করার জন্য, আপনি এইভাবে জোড় করে বলুন, প্রথম প্যারামিটারটি একটি স্ট্রিং, প্রথম অবজেক্টের সাথে স্ট্রিং হিসাবে কাস্টিং, পরবর্তী বস্তুটি একটি পূর্ণসংখ্যা ইত্যাদি হয় তবে আপনার প্রোগ্রামটি কার্যকর করার সাথে সাথে আপনি প্রথমে একটি ফাইল অবজেক্ট পাবেন, তারপরে একটি ডাবল ইত্যাদি,

এইভাবে, আপনি এই কেসগুলির জন্য অ্যাকাউন্ট করতে পারেন এবং কিছুটা "গতিশীল" অন ফ্লাইটে কাস্টিং তৈরি করতে পারেন।

আশা করি এটি গুগল অনুসন্ধানগুলিতে পরিণত হতে থাকায় এটি যে কাউকে সহায়তা করে।


0

আমি সম্প্রতি অনুভব করেছি যে আমারও এটি করতে হয়েছিল, তবে তারপরে অন্য একটি উপায় খুঁজে পেয়েছে যা সম্ভবত আমার কোডটি আরও সুন্দর দেখায় এবং আরও ভাল ওওপি ব্যবহার করে।

আমার অনেক ভাইবোনের ক্লাস রয়েছে যা প্রত্যেকে একটি নির্দিষ্ট পদ্ধতি প্রয়োগ করে 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);

আপনার কখনই গতিশীলভাবে কাস্ট করার প্রয়োজন হবে না। ডুসোমথিং () পদ্ধতিটি প্রয়োগ করে এমন সাব-ক্লাসিস এবং মেথডমোসেসিং () পদ্ধতিটির সাথে একটি সুপারক্লাস থাকার সূত্রটি ওওপি, পলিমারফিজমের অন্যতম প্রধান উদ্দেশ্য। অবজেক্ট foo = নতুন পূর্ণসংখ্যা ("1"); foo.toString () প্রদান করে ১. এটি বস্তুকে বরাদ্দ করা হলেও এটি একটি পূর্ণসংখ্যা এবং তাই এরূপ আচরণ করে। টু স্ট্রিং পদ্ধতিটি চালনা করে পূর্ণসংখ্যার বাস্তবায়ন চলবে। পলিমারফিজম।
জর্জি জাভিয়ার

0

কেবল ভেবেছিলাম আমি এমন কিছু পোস্ট করব যা আমি বেশ দরকারী বলে খুঁজে পেয়েছি এবং একইরকম চাহিদা অনুভব করা ব্যক্তির পক্ষে সম্ভব হতে পারে।

নিম্নলিখিত পদ্ধতিটি আমি জাভাএফএক্স অ্যাপ্লিকেশনটির জন্য লিখেছিলাম এমন একটি পদ্ধতি ছিল যাতে কাস্ট করা না হয় এবং লেখাটি এড়ানোর জন্য যদি প্রতিবার নিয়ামককে ফিরিয়ে দেওয়া হয় তবে অবজেক্ট বি স্টেটমেন্টের আইটেম এক্স উদাহরণস্বরূপ।

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()

শ্রেণীর অবজেক্টের মাধ্যমে আমার পদ্ধতিতে পাস হওয়া প্রকারের সাহায্যে, কোন ধরণের অবজেক্টটি ফিরে আসবে তা বলার জন্য এটি পদ্ধতিতে নিয়ন্ত্রক পেতে ফরোয়ার্ড করা যেতে পারে। ভুল শ্রেণীর সরবরাহের ক্ষেত্রে একটি alচ্ছিক বস্তু ফিরে আসে এবং একটি ব্যতিক্রম ঘটে সেই ক্ষেত্রে খালি alচ্ছিকটি ফিরে আসবে যা আমরা যাচাই করতে পারি।

পদ্ধতির চূড়ান্ত কলটি এটির মতো দেখায় (যদি প্রত্যাশিত theচ্ছিক বস্তুর উপস্থিতি কোনও গ্রাহক লাগে

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));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.