প্রতিবিম্ব দ্বারা গেটরকে অনুরোধ করার সর্বোত্তম উপায়


127

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

আমি জানি যে আমি "get + FieldName" সন্ধান করে পদ্ধতিটি সন্ধান করতে পারি (যদিও আমি জানি যে বুলিয়ান ক্ষেত্রগুলির জন্য উদাহরণস্বরূপ কখনও কখনও "is + FieldName" হিসাবে নামকরণ করা হয়)।

আমি আশ্চর্য হই যে এই গেটরকে ডাকার আরও ভাল কোনও উপায় আছে কিনা (অনেক ফ্রেমওয়ার্কগুলি বৈশিষ্ট্যগুলি অ্যাক্সেস করার জন্য গেটার / সেটার ব্যবহার করে যাতে তারা অন্য কোনও উপায়ে করতে পারে)।

ধন্যবাদ

উত্তর:


240

আমি মনে করি এটি আপনাকে সঠিক দিকের দিকে নির্দেশ করবে:

import java.beans.*

for (PropertyDescriptor pd : Introspector.getBeanInfo(Foo.class).getPropertyDescriptors()) {
  if (pd.getReadMethod() != null && !"class".equals(pd.getName()))
    System.out.println(pd.getReadMethod().invoke(foo));
}

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

// TODO check for non-existing readMethod
Object value = new PropertyDescriptor("name", Person.class).getReadMethod().invoke(person);

তবে, অনেকগুলি লাইব্রেরি রয়েছে যা java.beans API এ প্রসারিত ও সরল করে তুলেছে। কমন্স বিয়ান ইউটিস একটি সুপরিচিত উদাহরণ। সেখানে, আপনি কেবল এটি করতে চাই:

Object value = PropertyUtils.getProperty(person, "name");

বিয়ান ইউটিসস অন্যান্য হ্যান্ড স্টাফ নিয়ে আসে। অর্থাত্ ফ্লাই মান রূপান্তর (স্ট্রিং থেকে অবজেক্ট, স্ট্রিং টু অবজেক্ট) ব্যবহারকারীর ইনপুট থেকে বৈশিষ্ট্যগুলি সেট করে তুলতে।


আপনাকে অনেক ধন্যবাদ! এই স্ট্রিং ম্যানিপুলেশন ইত্যাদি থেকে আমাকে বাঁচায়!
গেরদা

1
অ্যাপাচি এর বিয়ান ইউটিলেস ভাল কল। বৈশিষ্ট্যগুলি অর্জন / সেটিং সহজ করে তোলে এবং ধরণের রূপান্তর পরিচালনা করে।
পিটার তাসেং

ক্ষেত্রগুলি জাভা ফাইলে তালিকাভুক্ত করার পদ্ধতিতে পদ্ধতিগুলি আহবান করার কোনও উপায় আছে কি?
লাইফএন্ডহপ

নীচে আমার উত্তর দেখুন @
আনন্দ

ভাল লাগল! অসাধারণ.
স্মাইলফ্লেস

20

আপনি এটির জন্য প্রতিচ্ছবি ফ্রেমওয়ার্ক ব্যবহার করতে পারেন

import static org.reflections.ReflectionUtils.*;
Set<Method> getters = ReflectionUtils.getAllMethods(someClass,
      withModifier(Modifier.PUBLIC), withPrefix("get"), withAnnotation(annotation));

সাবধান থাকুন যে প্রতিচ্ছবিগুলি এখনও জাভা 9 এর সাথে সামঞ্জস্যপূর্ণ নয়ক্লাস ইন্ডেক্স (সংকলনের সময়) এবং ক্লাসগ্রাফ (রান সময়) থ্রে থেকে বিকল্পগুলির জন্য আরও ভাল আচরণের জন্য লিঙ্ক রয়েছে।
ভাদজিম

এই সমাধানটিও আমলে নেবে না * গৃহীত উত্তরের শিম ইন্ট্রোস্পেক্টরের বিপরীতে প্রাপ্তরা।
ভাদজিম


3

আপনি প্রতিচ্ছবিগুলিও আহ্বান করতে পারেন এবং এন্টোটেশনের মাধ্যমে মানগুলির জন্য গতিপথের ক্রমও সেট করে

public class Student {

    private String grade;

    private String name;

    private String id;

    private String gender;

    private Method[] methods;

    @Retention(RetentionPolicy.RUNTIME)
    public @interface Order {
        int value();
    }

    /**
     * Sort methods as per Order Annotations
     * 
     * @return
     */
    private void sortMethods() {

        methods = Student.class.getMethods();

        Arrays.sort(methods, new Comparator<Method>() {
            public int compare(Method o1, Method o2) {
                Order or1 = o1.getAnnotation(Order.class);
                Order or2 = o2.getAnnotation(Order.class);
                if (or1 != null && or2 != null) {
                    return or1.value() - or2.value();
                }
                else if (or1 != null && or2 == null) {
                    return -1;
                }
                else if (or1 == null && or2 != null) {
                    return 1;
                }
                return o1.getName().compareTo(o2.getName());
            }
        });
    }

    /**
     * Read Elements
     * 
     * @return
     */
    public void readElements() {
        int pos = 0;
        /**
         * Sort Methods
         */
        if (methods == null) {
            sortMethods();
        }
        for (Method method : methods) {
            String name = method.getName();
            if (name.startsWith("get") && !name.equalsIgnoreCase("getClass")) {
                pos++;
                String value = "";
                try {
                    value = (String) method.invoke(this);
                }
                catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    e.printStackTrace();
                }
                System.out.println(name + " Pos: " + pos + " Value: " + value);
            }
        }
    }

    // /////////////////////// Getter and Setter Methods

    /**
     * @param grade
     * @param name
     * @param id
     * @param gender
     */
    public Student(String grade, String name, String id, String gender) {
        super();
        this.grade = grade;
        this.name = name;
        this.id = id;
        this.gender = gender;
    }

    /**
     * @return the grade
     */
    @Order(value = 4)
    public String getGrade() {
        return grade;
    }

    /**
     * @param grade the grade to set
     */
    public void setGrade(String grade) {
        this.grade = grade;
    }

    /**
     * @return the name
     */
    @Order(value = 2)
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the id
     */
    @Order(value = 1)
    public String getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the gender
     */
    @Order(value = 3)
    public String getGender() {
        return gender;
    }

    /**
     * @param gender the gender to set
     */
    public void setGender(String gender) {
        this.gender = gender;
    }

    /**
     * Main
     * 
     * @param args
     * @throws IOException
     * @throws SQLException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void main(String args[]) throws IOException, SQLException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        Student student = new Student("A", "Anand", "001", "Male");
        student.readElements();
    }
  }

বাছাই করার পরে আউটপুট

getId Pos: 1 Value: 001
getName Pos: 2 Value: Anand
getGender Pos: 3 Value: Male
getGrade Pos: 4 Value: A
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.