java.lang.reflect.Field ক্লাস

ফিল্ড ক্লাস একটি ক্লাস বা ইন্টারফেসের একটি একক ক্ষেত্রের সম্পর্কে তথ্য এবং গতিশীল অ্যাক্সেস সরবরাহ করে। ক্ষেত্রটি একটি গেট বা সেট অ্যাক্সেস অপারেশন চলাকালীন একটি প্রশস্তকরণের প্রকার রূপান্তরকেও অনুমতি দেয়, তবে সংকীর্ণতা ঘটলে একটি অবৈধ আর্গুমেন্ট এক্সেপশন নিক্ষেপ করে৷

একটি ফিল্ড অবজেক্ট পেতে , আমরা প্রথমে একটি ক্লাস লিখব:


public class Person {
    private String name;
    private int age;
    
    public boolean isMale;
    
    protected String address;
    
    public static final int MAX_AGE = 120;
    public static final int MIN_AGE = 0;
}

এবং এখানে সেই ক্লাসের সাথে কাজ করার জন্য আমাদের কোড:


public class Main {
    public static void main(String[] args) {
        Field[] fields = Person.class.getDeclaredFields();
        List<Field> actualFields = getFieldNames(fields);
        System.out.println(actualFields);
    }

    static List<Field> getFieldNames(Field[] fields) {
        return List.of(fields);
    }
}

এভাবেই আমরা আমাদের ক্লাসের ফিল্ডের তালিকা পাই, যেগুলো নিয়ে আমরা পরে কাজ করব। এখানে ফলাফল:

[private java.lang.String com.company.Person.name, private int com.company.Person.age, পাবলিক বুলিয়ান com.company.Person.isMale, সুরক্ষিত java.lang.String com.company.Person.address, পাবলিক স্ট্যাটিক ফাইনাল int com.company.Person.MAX_AGE, পাবলিক স্ট্যাটিক ফাইনাল int com.company.Person.MIN_AGE]

এখন আমরা এই ডেটা দিয়ে কি করতে পারি তা বের করা যাক। ফিল্ড ক্লাসের পদ্ধতি সম্পর্কে কথা বলা যাক :

পদ্ধতি বর্ণনা
getType() একটি ক্লাস অবজেক্ট প্রদান করে যা এটি দ্বারা উপস্থাপিত ক্ষেত্রের ঘোষিত প্রকার সনাক্ত করেমাঠবস্তু
গেট অ্যানোটেটেড টাইপ() একটি ফেরত দেয়টীকাযুক্ত প্রকারঅবজেক্ট যা এই ক্ষেত্র দ্বারা উপস্থাপিত ক্ষেত্রের ঘোষিত প্রকার নির্দিষ্ট করতে একটি প্রকারের ব্যবহারকে প্রতিনিধিত্ব করে।
getGenericType() ফেরত aটাইপঅবজেক্ট যা এটি দ্বারা উপস্থাপিত ক্ষেত্রের ঘোষিত প্রকারের প্রতিনিধিত্ব করেমাঠবস্তু
getName() এটি দ্বারা প্রতিনিধিত্ব করা ক্ষেত্রের নাম প্রদান করেমাঠবস্তু
getModifiers() এটি দ্বারা উপস্থাপিত ক্ষেত্রের জন্য জাভা ভাষা সংশোধক এনকোডিং একটি int প্রদান করেমাঠবস্তু
টীকা পান() এই ক্ষেত্রের জন্য টীকা প্রদান করে। কোন টীকা না থাকলে, এটি একটি খালি অ্যারে প্রদান করে।

getType(), getName(), এবং getModifiers() পদ্ধতি

আমরা আমাদের ক্ষেত্রের ধরন পেতে getType() পদ্ধতি ব্যবহার করতে পারি। আসুন একটি পদ্ধতি লিখি:


static void printTypes(List<Field> fields){
      fields.forEach(e -> System.out.println(e.getType()));
  }

এবং আমরা এই ফলাফল পাই:

ক্লাস java.lang.String
int
বুলিয়ান
ক্লাস java.lang.String
int
int

এখন একটি ক্ষেত্রের নাম পেতে আমাদের ক্লাসে একটি পদ্ধতি যোগ করা যাক। এটি আমাদের ক্লাসের ক্ষেত্রগুলিতে নেভিগেট করা সহজ করে তুলবে।


static void printTypesAndNames(List<Field> fields){
   fields.forEach(e -> System.out.printf("Field type - %s\nField name - %s\n\n", e.getType(), e.getName()));
}

এখন ফলাফল আরও বোধগম্য:

ফিল্ড টাইপ - ক্লাস java.lang.স্ট্রিং
ফিল্ডের নাম - নাম

ফিল্ড টাইপ - int
ফিল্ডের নাম - বয়স

ফিল্ড টাইপ - বুলিয়ান
ফিল্ডের নাম - isMale

ফিল্ড টাইপ - ক্লাস java.lang.স্ট্রিং
ফিল্ডের নাম - অ্যাড্রেস

ফিল্ড টাইপ - int
ফিল্ডের নাম - MAX_AGE

ক্ষেত্রের ধরন - int
ক্ষেত্রের নাম - MIN_AGE৷

দারুণ! আমাদের পদ্ধতি আরো কিছু পরিবর্তন করা যাক! আমরা এখানে অ্যাক্সেস মডিফায়ার যোগ করব


static void printFieldInfo(List<Field> fields){
   fields.forEach(e -> System.out.printf("Field type - %s\nField name - %s\nModifiers - %s\n\n", e.getType(), e.getName(), Modifier.toString(e.getModifiers())));
}

এবং আসুন দেখি e.getModifiers() কি রিটার্ন দেয়। এই পদ্ধতিটি একটি int প্রদান করে যা আমাদের ক্ষেত্রের অ্যাক্সেস মডিফায়ারের অবস্থা নির্ধারণ করতে দেয়। পরিবর্তক শ্রেণীতে ক্ষেত্রটির প্রতিটি নির্দিষ্ট পরিবর্তনকারীর জন্য দায়ী স্ট্যাটিক ভেরিয়েবল রয়েছে

আসুন Modifier.toString() তে আমাদের রিটার্ন মান মুড়ে ফেলি এবং অবিলম্বে পাঠ্য হিসাবে এর মানটি পান:

ক্ষেত্রের ধরন - ক্লাস java.lang.String
ক্ষেত্রের নাম - নাম
পরিবর্তনকারী - ব্যক্তিগত

ক্ষেত্রের ধরন - int
ক্ষেত্রের নাম - বয়স
সংশোধক - ব্যক্তিগত

ক্ষেত্রের প্রকার - বুলিয়ান
ক্ষেত্রের নাম - isMale
Modifiers - সর্বজনীন

ক্ষেত্রের ধরন - class java.lang.String
ক্ষেত্রের নাম - ঠিকানা
সংশোধক - সুরক্ষিত

ক্ষেত্রের প্রকার - int
ক্ষেত্রের নাম - MAX_AGE
সংশোধক - সর্বজনীন স্ট্যাটিক চূড়ান্ত

ক্ষেত্রের প্রকার - int
ক্ষেত্রের নাম - MIN_AGE
সংশোধক - সর্বজনীন স্ট্যাটিক চূড়ান্ত

Modifier.toString() ছাড়া এটি দেখতে কেমন তা এখানে :

ফিল্ড টাইপ - ক্লাস java.lang.স্ট্রিং
ফিল্ডের নাম - নাম
পরিবর্তনকারী - 2

ফিল্ড টাইপ - int
ফিল্ডের নাম - বয়স
পরিবর্তনকারী - 2

ফিল্ড টাইপ - বুলিয়ান
ফিল্ডের নাম - isMale
Modifiers - 1

ফিল্ড টাইপ - class java.lang.String
ফিল্ডের নাম - ঠিকানা
সংশোধক - 4

ক্ষেত্র প্রকার - int
ক্ষেত্রের নাম - MAX_AGE
সংশোধক - 25

ক্ষেত্রের প্রকার - int
ক্ষেত্রের নাম - MIN_AGE
সংশোধক - 25

getAnnotations(), getAnnotatedType(), এবং getGenericType() পদ্ধতি

আসুন এই পদ্ধতিগুলির সাথে কাজ করার জন্য ব্যক্তি শ্রেণীর পরিবর্তন করি। আমরা আমাদের নিজস্ব টীকা লিখব এবং এটি আমাদের ক্ষেত্রগুলিতে প্রয়োগ করব৷ এবং আমরা আরো কয়েকটি ক্ষেত্র যোগ করব।

এর দুটি টীকা তৈরি করা যাক. আমরা পিগ ল্যাটিনে ভেরিয়েবলের নামটি একটিতে পাস করব এবং আমরা উপাদানগুলির জন্য দ্বিতীয়টি ব্যবহার করব:


@Target(value=ElementType.FIELD)
@Retention(value= RetentionPolicy.RUNTIME)
public @interface Name {
    String name();
}

@Target({ ElementType.TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Number {
}

এবং আমরা আমাদের প্রধান শ্রেণী এবং ব্যক্তি শ্রেণীর পরিবর্তন করব :


public class Person {
    @Name(name = "Ame-nay")
    private String name;

    @Name(name = "User nicknames")
    List<String> nicknames;

    private final Class<Object> type;

    private int @Number[] number;

    public Person(Class<Object> type) {
        this.type = type;
    }
}

public static void main(String[] args) {
    Field[] fields = Person.class.getDeclaredFields();
    List<Field> actualFields = getFieldNames(fields);
    
    printAdditionalInfo(actualFields);
}

static void printAdditionalInfo(List<Field> fields) {
   System.out.println("\ngetAnnotatedType:");
   fields.forEach(e -> System.out.println(e.getAnnotatedType()));

   System.out.println("\ngetGenericType:");
   fields.forEach(e -> System.out.println(e.getGenericType()));

   System.out.println("\ngetAnnotations:");
   fields.forEach(e -> System.out.println(Arrays.toString(e.getAnnotations())));
}

আমাদের পদ্ধতিগুলির ফলাফলগুলি দেখার এবং সেগুলি কীসের জন্য তা নির্ধারণ করার সময় এসেছে:

getAnnotatedType:
java.lang.Class<java.lang.Object>
java.util.List<java.lang.String>
java.lang.String
int @Number()[]

getGenericType:
java.lang.Class<java.lang। অবজেক্ট>
java.util.List<java.lang.String>
ক্লাস java.lang.String
ক্লাস [আমি

টীকা পাই:
[]
[@Name(name="\u0055\u0073\u0065\u0072\u0020\u006e\u0069\u0063) \u006b\u006e\u0061\u006d\u0065\u0073")]
[@Name(name="\u0041\u006d\u0065\u002d\u006e\u0061\u0079")] [
]
  • getAnnotatedType প্রদত্ত ক্ষেত্রের জন্য টীকা প্রদান করে, যদি থাকে। আমরা ক্ষেত্রের জন্য টীকা পাই এবং আমরা এটি পুরোপুরি দেখতে পারি।

  • getGenericType আপনাকে সঠিকভাবে একটি প্যারামিটারাইজড টাইপ প্রদর্শন করতে দেয়।

  • getAnnotations আমাদের অবজেক্টে প্রয়োগ করা টীকা ফেরত দেয়।

এইভাবে আমরা আমাদের ক্লাসের প্রতিটি ক্ষেত্রের সমস্ত ডেটা, সেইসাথে এর অ্যাক্সেস মডিফায়ার, টীকা এবং ডেটা প্রকারগুলি সহজেই পেতে পারি।

java.lang.reflect.Method ক্লাস

সুপার! আমরা আমাদের ক্লাসের ক্ষেত্র সম্পর্কে কথা বলেছি। এখন পদ্ধতি সম্পর্কে কথা বলার সময়।

একটি Method অবজেক্ট পেতে , আমরা getMethod পদ্ধতিকে কল করি, এটিকে আমাদের পদ্ধতির নাম দিয়েছি। এটি একটি পদ্ধতি বস্তু পেতে মৌলিক উপায় :


Method getNameMethod =  Person.class.getMethod("getName");

আমরা আমাদের ক্লাসের সাথে কাজ চালিয়ে যাব। আসুন গেটার এবং সেটার্স এবং হ্যাশকোড, সমান এবং টু স্ট্রিং পদ্ধতি যোগ করি:


public class Person {
    private String name;
    private int age;

    public boolean isMale;

    protected String address;

    public static final int MAX_AGE = 120;
    public static final int MIN_AGE = 0;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMale() {
        return isMale;
    }

    public void setMale(boolean male) {
        isMale = male;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", isMale=" + isMale +
                ", address='" + address + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && isMale == person.isMale && Objects.equals(name, person.name) && Objects.equals(address, person.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, isMale, address);
    }
}

এখন পদ্ধতির একটি সেট প্রস্তুত করা যাক যা আমরা মেথড ক্লাস ব্যবহার করে পরীক্ষা করব। এখানে সবচেয়ে গুরুত্বপূর্ণ পদ্ধতিগুলির একটি তালিকা রয়েছে:

পদ্ধতি বর্ণনা
getName() পদ্ধতির নাম প্রদান করে।
getModifiers() এই পদ্ধতির অ্যাক্সেস মডিফায়ার প্রদান করে।
getReturnType() পদ্ধতির রিটার্ন প্রকার প্রদান করে।
getGenericReturnType() জেনেরিক পদ্ধতির জন্য অ্যাকাউন্টিং পদ্ধতির রিটার্ন টাইপ প্রদান করে।
getParameterTypes() পদ্ধতি পরামিতিগুলির একটি অ্যারে প্রদান করে।
getGenericParameterTypes() জেনেরিক পদ্ধতির জন্য অ্যাকাউন্টিং পদ্ধতির পরামিতিগুলির একটি অ্যারে প্রদান করে।
getExceptionTypes() পদ্ধতিটি নিক্ষেপ করতে পারে এমন ব্যতিক্রমগুলি প্রদান করে।
getGenericExceptionTypes() প্যারামিটারাইজড প্রকারের জন্য অ্যাকাউন্টিং পদ্ধতিটি ছুঁড়ে দিতে পারে এমন ব্যতিক্রমগুলি প্রদান করে।
টীকা পান() প্যারেন্ট টীকা সহ পদ্ধতির জন্য টীকা ফেরত দেয়।
getDeclaredAnotations() প্যারেন্ট টীকা বাদ দিয়ে পদ্ধতির জন্য টীকা ফেরত দেয়।

আমাদের ক্লাস উইলের পদ্ধতিগুলির একটি অ্যারে পেতে, আমরা এই পদ্ধতিটিকে কল করতে পারি:


Method[] methods = Person.class.getDeclaredMethods();

এটি আমাদের ক্লাসের সমস্ত পদ্ধতি দেবে।

getName() এবং getModifiers() পদ্ধতি

আমরা প্রতিটি পদ্ধতির নাম পেতে getName ব্যবহার করতে পারি:


static List<String> getMethodsName(Method[] methods) {
    return Arrays.asList(methods)
            .stream()
            .map(Method::getName)
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}

এখন মডিফায়ারগুলি পেতে, আসুন একটি পদ্ধতি লিখি যা getModifiers ব্যবহার করে :


static List<String> getModifiers(Method[] methods) {
    return Arrays
            .stream(methods)
            .map(Method::getModifiers)
            .map(String::valueOf)
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}

এখানে আমাদের প্রধান পদ্ধতি:


public static void main(String[] args) {
    Method[] methods = Person.class.getDeclaredMethods();

    System.out.println(getMethodsName(methods));
    System.out.println(getModifiers(methods));
}

আমাদের ফলাফল:

[getName, equals, toString, hashCode, setName, getAddress, isMale, getAge, setAge, setMale, setAddress]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

আমাদের সমস্ত পদ্ধতিতে পাবলিক মডিফায়ার রয়েছে, তাই শেষ পদ্ধতিটি একটি অ্যারে প্রদান করে। যদি আমরা আমাদের কোড পরিবর্তন করি, তাহলে আমরা আমাদের সংশোধকগুলি নিজেই দেখতে পাব:


public static void main(String[] args) {
    Method[] methods = Person.class.getDeclaredMethods();

    System.out.println(getMethodsName(methods));
    System.out.println(modifyModifiers(getModifiers(methods)));
}
[getName, equals, toString, hashCode, setName, getAddress, isMale, getAge, setAge, setMale, setAddress] [সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন, সর্বজনীন,
সর্বজনীন

getReturnedType()

এই পদ্ধতিটি আমাদেরকে পদ্ধতির রিটার্ন টাইপ পেতে দেয়:


static void getReturnedType(Method[] methods) {
    Arrays.stream(methods)
            .map(Method::getReturnType)
            .forEach(System.out::println);
}
ক্লাস java.lang.String
বুলিয়ান
ক্লাস java.lang.String
int
void
class java.lang.String
বুলিয়ান
int
void
void
void

getGenericReturnType()

আসুন আমাদের ব্যক্তি শ্রেণিকে একটি পদ্ধতি দিই যা একটি প্যারামিটারাইজড টাইপে মোড়ানো টাইপটি ফেরত দেয় এবং এর রিটার্ন মান পেতে চেষ্টা করুন:


public List<String> someMethod() {
    // Very useful and important method
    return null;
}

এবং আমরা আমাদের প্রধান পদ্ধতি আপডেট করব:


static void getGenericReturnType(Method[] methods) {
    Arrays.stream(methods)
            .map(Method::getGenericReturnType)
            .forEach(System.out::println);
}

আমাদের পদ্ধতির ফলাফল:

ক্লাস java.lang.String
বুলিয়ান
ক্লাস java.lang.String
int
void
class java.lang.String
বুলিয়ান
int
void
void
void
java.util.List<java.lang.String>

getParameterTypes() এবং getGenericParameterTypes() পদ্ধতি

আমরা আরও দুটি পদ্ধতি যোগ করে আমাদের ব্যক্তি শ্রেণিকে সংশোধন করতে থাকি :


public List<String> someMethod(List<String> list, String s) {
    // Very useful and important method
    return null;
}

প্রথমটি আমাদের পদ্ধতির পরামিতি পেতে দেবে, এবং দ্বিতীয়টি আমাদের প্যারামিটারাইজড প্রকারগুলিও দেবে।


static void getParameterTypes(Method[] methods) {
    Class<?>[] types = method.getParameterTypes();
        for (Class<?> type : types) {
            System.out.println(type);
        }
}

static void getGenericParameterTypes(Method[] methods) {
   Type[] types = method.getGenericParameterTypes();
        for (Type type : types) {
            System.out.println(type);
        }
}

আমরা আমাদের শুধুমাত্র একটি পদ্ধতি অ্যাক্সেস করব। একটি নির্দিষ্ট নামে একটি পদ্ধতি অ্যাক্সেস করতে, আমরা getMethod কল করি এবং আমরা যে পদ্ধতিটি চাই তার নাম এবং পরামিতিগুলি পাস করি:


public static void main(String[] args) throws NoSuchMethodException {
    Method currentMethod = Person.class.getMethod("someMethod", List.class, String.class);

    getParameterTypes(currentMethod);
    System.out.println();
    getGenericParameterTypes(currentMethod);
}

আমাদের কোড চলমান, আমরা দেখতে পাব যে পদ্ধতিগুলি কীভাবে আলাদা হয় এবং তারা কী ফেরত দেয়:

ইন্টারফেস java.util.List
class java.lang.String

java.util.List<java.lang.String>
ক্লাস java.lang.String

getExceptionTypes() এবং getGenericExceptionTypes() পদ্ধতি

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


private static class Processor {
    private void init() {}

    private void process() throws IOException {}
}

এবং আমরা আমাদের প্রসেসর ক্লাসে পদ্ধতিগুলি কল করব :


public static void main(String... args) throws NoSuchMethodException {
    Method method = Processor.class.getDeclaredMethod("process");
    Type[] type = method.getExceptionTypes();
    System.out.println(Arrays.toString(type));
}

এখন আমরা আমাদের ব্যতিক্রম দেখতে পারি:

[ক্লাস java.io.IOException]

এখন ধরন প্যারামিটারাইজ করা যাক। আমরা আমাদের প্রধান ক্লাস সংশোধন করব:


private static class Processor<E extends IOException> {

    private void process() throws E {
    }
}

এবং প্রধান পদ্ধতির কোড :


public static void main(String... args) throws NoSuchMethodException {
    Method m = Processor.class.getDeclaredMethod("process");
    Type[] t = m.getGenericExceptionTypes();
    System.out.println(Arrays.toString(t));

    for (Type type : t) {
        if (type instanceof TypeVariable) {
            for (Type type1 : ((TypeVariable) type).getBounds()) {
                System.out.println(type1);
            }
        }
    }
}

এই পদ্ধতির ভিতরে, আমরা একটি TypeVariables অবজেক্ট পেয়েছি, যা টাইপ ভেরিয়েবলের জন্য একটি জেনেরিক প্যারেন্ট ইন্টারফেস। এবং এর ভিতরে, আমরা এখন অভ্যন্তরীণ প্যারামিটার পেতে পারি, যথা আমাদের নেস্টেড ব্যতিক্রম:

[E]
ক্লাস java.io.IOException

getAnnotations() এবং getDeclaredAnnotations() পদ্ধতি

আসুন এই নতুন ক্লাসটি ব্যবহার করা চালিয়ে যাই এবং এতে কয়েকটি টীকা যোগ করি। আমরা আমাদের নিজস্ব টীকা টীকা তৈরি করব :


@Retention(RetentionPolicy.RUNTIME)
@interface Annotation {

    public String key();
    public String value();
}

এবং আমাদের পদ্ধতিতে এটি প্রয়োগ করুন:


@Annotation(key = "key", value = "value")
private void process() throws E{

}

এবং অবশ্যই আমরা আমাদের সমস্ত টীকা প্রদর্শন করার জন্য একটি পদ্ধতি যুক্ত করব:


static void getMethodAnnotations(Class<?> clazz) {
    Method[] methods = clazz.getDeclaredMethods();
    for (Method method : methods) {
        System.out.println(method.getName());
        System.out.println(Arrays.toString(method.getAnnotations()));
        System.out.println();
    }
}

আমাদের প্রধান পদ্ধতির বাস্তবায়ন:


public static void main(String... args) {
    Class clazz = Processor.class;
    getMethodAnnotations(clazz);
}

ফলে স্ক্রীন আউটপুট হল:

প্রক্রিয়া
[@com.company.Main&Anotation(key="key", value="value")]

এইভাবে আমরা আমাদের পদ্ধতিতে প্রয়োগ করা টীকাগুলি পেতে পারি এবং getAnnotations পদ্ধতিটি আমাদের ক্লাসের মূল টীকাগুলিও অ্যাক্সেস করতে দেয়।

প্রতিফলন পদ্ধতি এবং ক্ষেত্রগুলির সাথে কীভাবে কাজ করতে পারে এবং এর সাথে আমরা কী ডেটা পেতে পারি তার সাথে আজ আমরা পরিচিত হয়েছি!