java.lang.reflect.Field वर्ग

फील्ड क्लास वर्ग किंवा इंटरफेसच्या एकाच फील्डबद्दल माहिती आणि डायनॅमिक ऍक्सेस प्रदान करतो. फील्ड गेट किंवा सेट ऍक्सेस ऑपरेशन दरम्यान रुंदीकरण प्रकार रूपांतरणास देखील अनुमती देते, परंतु जर अरुंद होत असेल तर एक IllegalArgumentException टाकते.

फील्ड ऑब्जेक्ट मिळविण्यासाठी , आम्ही प्रथम एक वर्ग लिहू:


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

अशा प्रकारे आम्हाला आमच्या वर्गाच्या फील्डची यादी मिळेल, ज्यावर आम्ही नंतर कार्य करू. हा निकाल आहे:

[खाजगी java.lang.String com.company.Person.name, खाजगी 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() याद्वारे दर्शविलेल्या फील्डचा घोषित प्रकार ओळखणारी क्लास ऑब्जेक्ट मिळवतेफील्डवस्तू
GetAnnotatedType() एक परत करतोभाष्य प्रकारऑब्जेक्ट जे या फील्डद्वारे दर्शविलेल्या फील्डचा घोषित प्रकार निर्दिष्ट करण्यासाठी प्रकाराचा वापर दर्शवते.
getGenericType() परतावा aप्रकारऑब्जेक्ट जे याद्वारे दर्शविलेल्या फील्डच्या घोषित प्रकाराचे प्रतिनिधित्व करतेफील्डवस्तू
getName() याद्वारे दर्शविलेल्या फील्डचे नाव मिळवतेफील्डवस्तू
getModifiers() याद्वारे दर्शविलेल्या फील्डसाठी Java भाषा मॉडिफायर्स एन्कोडिंग एक 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.String
फील्ड नाव - नाव

फील्ड प्रकार - int
फील्ड नाव - वय

फील्ड प्रकार - बुलियन
फील्ड नाव - isMale

फील्ड प्रकार - वर्ग java.lang.String
फील्ड नाव - पत्ता

फील्ड प्रकार - int
फील्ड नाव - MAX_AGE

फील्ड प्रकार - इंट
फील्ड नाव - 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 - सार्वजनिक

फील्ड प्रकार - वर्ग java.lang.String
फील्ड नाव - पत्ता
सुधारक - संरक्षित

फील्ड प्रकार - इंट
फील्ड नाव - MAX_AGE
सुधारक - सार्वजनिक स्थिर अंतिम

फील्ड प्रकार - इंट
फील्ड नाव - MIN_AGE
सुधारक - सार्वजनिक स्थिर अंतिम

Modifier.toString() शिवाय ते कसे दिसते ते येथे आहे :

फील्ड प्रकार - वर्ग java.lang.String
फील्ड नाव - नाव
सुधारक - 2

फील्ड प्रकार - int
फील्ड नाव - वय
सुधारक - 2

फील्ड प्रकार - बुलियन
फील्ड नाव - isMale
मॉडिफायर्स - 1

फील्ड प्रकार - वर्ग 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 वर्ग

उत्कृष्ट! आम्ही आमच्या वर्गाच्या फील्डबद्दल बोललो. आता पद्धतींबद्दल बोलण्याची वेळ आली आहे.

मेथड ऑब्जेक्ट मिळविण्यासाठी , आम्ही 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
boolean
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
वर्ग 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 ऑब्जेक्ट मिळाला आहे, जो प्रकार व्हेरिएबल्ससाठी एक सामान्य पालक इंटरफेस आहे. आणि त्यामध्ये, आम्ही आता अंतर्गत पॅरामीटर मिळवू शकतो, म्हणजे आमचा नेस्टेड अपवाद:

[ई]
वर्ग 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 पद्धतीमुळे आम्हाला वर्गाच्या मूळ भाष्यांमध्येही प्रवेश मिळू शकतो.

आज आम्हाला परावर्तन पद्धती आणि फील्डसह कसे कार्य करू शकते आणि त्याद्वारे आम्हाला कोणता डेटा मिळू शकतो याची ओळख झाली!