প্রতিবিম্ব জেনেরিক ক্ষেত্রের মান পান


132

আমি প্রতিচ্ছবি মাধ্যমে ক্ষেত্রের মান গ্রহণ করার চেষ্টা করছি। সমস্যাটি হ'ল আমি ক্ষেত্রের প্রকারটি জানি না এবং মান পাওয়ার সময় এটি সিদ্ধান্ত নিতে হয়।

এই কোডটি এই ব্যতিক্রম সহ ফলাফল দেয়:

Java.lang.String ফিল্ড কম সেট করতে পারবেন না .... ফিল্ড নেম java.lang.String এ

Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);

Class<?> targetType = field.getType();
Object objectValue = targetType.newInstance();

Object value = field.get(objectValue);

আমি কাস্ট করার চেষ্টা করেছি, তবে সংকলনের ত্রুটি পেয়েছি:

field.get((targetType)objectValue)

অথবা

targetType objectValue = targetType.newInstance();

কিভাবে আমি এটি করতে পারব?


4
এ খুঁজছি এপিআই , যুক্তি field.get()হওয়া উচিত object, তাই না objectValue
ওরফেড আইওটি

উত্তর:


144

আগে উত্তর মত, আপনার ব্যবহার করা উচিত:

Object value = field.get(objectInstance);

আরেকটি উপায়, যা কখনও কখনও পছন্দসই হয়, তাকে গতিশীলভাবে কল করে। উদাহরণ কোড:

public static Object runGetter(Field field, BaseValidationObject o)
{
    // MZ: Find the correct method
    for (Method method : o.getMethods())
    {
        if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
        {
            if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
            {
                // MZ: Method found, run it
                try
                {
                    return method.invoke(o);
                }
                catch (IllegalAccessException e)
                {
                    Logger.fatal("Could not determine method: " + method.getName());
                }
                catch (InvocationTargetException e)
                {
                    Logger.fatal("Could not determine method: " + method.getName());
                }

            }
        }
    }


    return null;
}

এও সচেতন থাকুন যে যখন আপনার শ্রেণি অন্য ক্লাসের উত্তরাধিকার সূত্রে আসে তখন আপনাকে পুনরাবৃত্তভাবে ক্ষেত্রটি নির্ধারণ করতে হবে। উদাহরণস্বরূপ, প্রদত্ত শ্রেণীর সমস্ত ক্ষেত্রগুলি আনা;

    for (Class<?> c = someClass; c != null; c = c.getSuperclass())
    {
        Field[] fields = c.getDeclaredFields();
        for (Field classField : fields)
        {
            result.add(classField);
        }
    }

1
এটি একেবারেই সত্য বলে মনে হচ্ছে না যে আপনাকে নিজেরাই সুপার ক্লাসের মাধ্যমে পুনরাবৃত্তি করতে হবে। সি.জেটফিল্ডস () বা সি.গেটফিল্ড () প্রতিটি প্রয়োগকারী ইন্টারফেসে স্বয়ংক্রিয়ভাবে ক্ষেত্রটি অনুসন্ধান করবে এবং সমস্ত সুপারক্লাসের মাধ্যমে পুনরাবৃত্তভাবে। সুতরাং getDeclaredX থেকে getX এ স্যুইচ করার পক্ষে এটি যথেষ্ট।
প্রেমেসিয়াউ ńadyński

3
প্রকৃতপক্ষে, গেটফিল্ডস () রুটিন আপনাকে সমস্ত সুপার ক্লাস এবং ইন্টারফেসের জন্য ক্ষেত্রগুলি আনতে অনুমতি দেবে, তবে কেবল সর্বজনীন। সাধারণত, ক্ষেত্রগুলি ব্যক্তিগত / সুরক্ষিত করা হয় এবং গিটার / সেটারগুলির মাধ্যমে উন্মুক্ত করা হয়।
মারিউস

@ মারিয়াস, আমি কি জানতে পারি প্যাকেজটি কী BaseValidationObject?
র্যান্ডটিয়ান

@ রানডায়ান, এটি আমার ব্যক্তিগত কোড ভাণ্ডারের মধ্যে রয়েছে, আপনি এটি অবজেক্টের সাথে প্রতিস্থাপন করতে পারেন। একই স্ট্যাটিক লগার কলগুলিতে প্রযোজ্য, তাদের আপনার নিজস্ব লগার (উদাহরণ) দিয়ে প্রতিস্থাপন করুন।
মারিয়াস

@ মারিয়াস objectক্লাসে পদ্ধতি নেই getMethods()। কোন পরামর্শ?
র্যান্ডিতান

127

আপনি পাস করা উচিত বস্তুর করার পেতে পদ্ধতি ক্ষেত্র , তাই

  Field field = object.getClass().getDeclaredField(fieldName);    
  field.setAccessible(true);
  Object value = field.get(object);

6
ফিল্ড.জেট (অবজেক্ট) - এ অবজেক্টটি কেন ব্যবহার করতে হবে তার কারণ আপনি কী জানেন - ক্ষেত্রটি নিজেই সেই বস্তু থেকে আসে, কেন আবার এটির প্রয়োজন হয় না?!
সেরুপ

18
@ সিরাপ নো, ফিল্ড অবজেক্ট ক্লাস অবজেক্ট থেকে আসে, এটির আপনার প্রকৃত উদাহরণের সাথে কোনও সংযোগ নেই। ( object.getClass()আপনাকে এই শ্রেণীর বস্তুটি ফিরিয়ে দেবে)
দিমিত্রি স্পিখালস্কি

1
objectস্নিপেটে সংজ্ঞায়িত করা হয়নি তাই পাঠকরা কীভাবে এটি ব্যবহার করবেন তা বুঝতে পারবেন না।
ঝিল্টেরেস

সেক্ষেত্রে @ খিল্টেরাস, তাদের এখনও প্রতিবিম্ব ব্যবহার করা উচিত নয় এবং প্রথমে কিছু প্রাথমিক দক্ষতা পাওয়া উচিত 🤷🏻‍♂️ ♂️ প্রতিবিম্ব একটি উন্নত পর্যাপ্ত বিষয় যা এটি ব্যাখ্যা না করতে পারে যে একটি পরিবর্তনশীল objectমানে আমাদের টার্গেট অবজেক্ট / দৃষ্টান্ত যার সাথে আমরা কাজ করি। আমি মনে করি যে পাঠকরা objectএই উত্তরের সাথে যা আছে তা আসলে পুরোপুরি ভাল ।
দিমিত্রি স্পিখালস্কি

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

19

ক্লাসের সদস্য এবং মানগুলি (সহজ এবং দ্রুত ডিবাগিং) দেখতে আমি আমার পছন্দ শ্রেণীর টোস্ট্রিং () বাস্তবায়নের প্রতিচ্ছবি ব্যবহার করি।

সরলীকৃত কোড আমি ব্যবহার করছি:

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();

    Class<?> thisClass = null;
    try {
        thisClass = Class.forName(this.getClass().getName());

        Field[] aClassFields = thisClass.getDeclaredFields();
        sb.append(this.getClass().getSimpleName() + " [ ");
        for(Field f : aClassFields){
            String fName = f.getName();
            sb.append("(" + f.getType() + ") " + fName + " = " + f.get(this) + ", ");
        }
        sb.append("]");
    } catch (Exception e) {
        e.printStackTrace();
    }

    return sb.toString();
}

আমি আশা করি এটি কারও সাহায্য করবে, কারণ আমিও অনুসন্ধান করেছি।


12

আপনি কী অর্জন করতে চাইছেন তা আমার কাছে সত্যই স্পষ্ট না হলেও আমি আপনার কোডে একটি স্পষ্ট ত্রুটি চিহ্নিত করেছি: Field.get()প্রত্যাশাটিটি ক্ষেত্রটি আর্গুমেন্ট হিসাবে অন্তর্ভুক্ত রেখেছে, ক্ষেত্রটির কিছু (সম্ভাব্য) মান নয়। সুতরাং আপনার উচিত field.get(object)

যেহেতু আপনি ক্ষেত্রের মানটি সন্ধান করছেন বলে মনে হচ্ছে, আপনি এটি হিসাবে পেতে পারেন:

Object objectValue = field.get(object);

ক্ষেত্রের প্রকারটি ইনস্ট্যান্ট করে কিছু খালি / ডিফল্ট মান তৈরি করার দরকার নেই; অথবা হতে পারে এমন কিছু আছে যা আমি মিস করেছি।


2
objectসংজ্ঞায়িত করা হয়নি, পাঠকরা উত্তরটি কীভাবে প্রয়োগ করবেন তা বুঝতে পারবেন না।
ঝিল্টেরেস

10
 Integer typeValue = 0;
 try {
     Class<Types> types = Types.class;
     java.lang.reflect.Field field = types.getDeclaredField("Type");
     field.setAccessible(true);
     Object value = field.get(types);
     typeValue = (Integer) value;
 } catch (Exception e) {
     e.printStackTrace();
 }

4

আপনি ভুল যুক্তি দিয়ে get কল করছেন।

এটা করা উচিত:

Object value = field.get(object);

2
objectসংজ্ঞায়িত করা হয়নি, পাঠকরা উত্তরে উদাহরণটি কীভাবে প্রয়োগ করবেন তা বুঝতে পারবেন না
ঝিল্টেরাস

2

আমি আমার সমাধানটি কোটলিনে পোস্ট করি তবে এটি জাভা বস্তুগুলির সাথেও কাজ করতে পারে। আমি কোনও ফাংশন এক্সটেনশন তৈরি করি যাতে কোনও বস্তু এই ফাংশনটি ব্যবহার করতে পারে।

fun Any.iterateOverComponents() {

val fields = this.javaClass.declaredFields

fields.forEachIndexed { i, field ->

    fields[i].isAccessible = true
    // get value of the fields
    val value = fields[i].get(this)

    // print result
    Log.w("Msg", "Value of Field "
            + fields[i].name
            + " is " + value)
}}

এই ওয়েবপৃষ্ঠায় একবার দেখুন: https://www.geeksforgeeks.org/field-get-method-in-java-with-ex উদাহরণ/


1
    ` 
//Here is the example I used for get the field name also the field value
//Hope This will help to someone
TestModel model = new TestModel ("MyDate", "MyTime", "OUT");
//Get All the fields of the class
 Field[] fields = model.getClass().getDeclaredFields();
//If the field is private make the field to accessible true
fields[0].setAccessible(true);
//Get the field name
  System.out.println(fields[0].getName());
//Get the field value
System.out.println(fields[0].get(model));
`
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.