CodeGym /Kurslar /JAVA 25 SELF /Siniflər, sahələr və metodlar haqqında məlumatın alınması...

Siniflər, sahələr və metodlar haqqında məlumatın alınması

JAVA 25 SELF
Səviyyə , Dərs
Mövcuddur

1. Sahələr haqqında məlumatın alınması

getFields()getDeclaredFields() nə ilə fərqlənir

Java-da hər bir sinifin sahələri (fields) var — sinifin daxilində elan edilmiş dəyişənlər. Refleksiya vasitəsilə onların adlarını, tiplərini, giriş modifikatorlarını (public/private) öyrənə və həmçinin icra zamanı onlara çıxış əldə edə bilərik. Əsas giriş nöqtəsi — Class<?> obyekti.

Sahələrlə işləmək üçün Class sinifinin əsas metodları:

Metod Nə qaytarır
getFields()
Sinifin, onun üst siniflərinin və interfeyslərinin bütün public sahələrinin massivi
getDeclaredFields()
Bütün bu sinifdə elan edilmiş sahələrin massivi

Oxşarlıq: getFields() — sanki yalnız nümayiş zallarına (public) ekskursiyadır, getDeclaredFields() isə — əlavə olaraq texniki otaqlara da (private, protected, package-private).

Nümunə: sinifin bütün sahələrini çıxarırıq

Tutaq ki, bizdə belə bir sinif var:

public class Person {
    public String name;
    private int age;
    protected String email;
}

Sahələr haqqında məlumat alaq:

import java.lang.reflect.Field;

Class<?> clazz = Person.class;

// Bütün public sahələr (miras alınanlar daxil olmaqla)
System.out.println("Public fields:");
for (Field field : clazz.getFields()) {
    System.out.println(field.getName() + " : " + field.getType().getSimpleName());
}

// Bu sinifdə elan edilən bütün sahələr (private daxil olmaqla, yalnız bu sinfin sahələri)
System.out.println("\nDeclared fields:");
for (Field field : clazz.getDeclaredFields()) {
    System.out.println(field.getName() + " : " + field.getType().getSimpleName());
}

Nəticə:

Public fields:
name : String

Declared fields:
name : String
age : int
email : String

Sahənin modifikatorlarını necə öyrənmək olar?

Hər bir sahənin (Field) modifikatorları var (public/private/protected, static, final və s.). Onları getModifiers() vasitəsilə almaq və Modifier ilə sətirə çevirmək olar:

import java.lang.reflect.Modifier;

for (Field field : clazz.getDeclaredFields()) {
    int mods = field.getModifiers();
    System.out.println(field.getName() + " : " + Modifier.toString(mods));
}

2. Metodlar haqqında məlumatın alınması

getMethods()getDeclaredMethods() metodları

Metodlar — obyektin yerinə yetirə bildiyi əməliyyatlardır. Refleksiya vasitəsilə sinifdə hansı metodların olduğunu, onların parametrlərini, qaytardığı tipləri, modifikatorlarını və annotasiyalarını öyrənmək olar.

Metod Nə qaytarır
getMethods()
Sinifin və onun üst siniflərinin bütün public metodları (Object daxil olmaqla)
getDeclaredMethods()
Bu sinifdə elan edilən bütün metodlar (private daxil olmaqla)

Nümunə: sinifin bütün metodlarını çıxarırıq

import java.lang.reflect.Method;

System.out.println("Public methods:");
for (Method method : clazz.getMethods()) {
    System.out.println(method.getName());
}

System.out.println("\nDeclared methods:");
for (Method method : clazz.getDeclaredMethods()) {
    System.out.println(method.getName());
}

Nəticə (Person üçün):

Public methods:
getClass
hashCode
equals
toString
notify
notifyAll
wait
wait
wait

Declared methods:
(heç nə, əgər Person daxilində öz metodları elan edilməyibsə)

Person-a metod əlavə edək:

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

    public void sayHello() {
        System.out.println("Hi!");
    }
}

İndi getDeclaredMethods() onu da göstərəcək.

Metodun parametrlərini və qaytarma tipini necə öyrənmək olar?

for (Method method : clazz.getDeclaredMethods()) {
    System.out.print(Modifier.toString(method.getModifiers()) + " ");
    System.out.print(method.getReturnType().getSimpleName() + " ");
    System.out.print(method.getName() + "(");
    Class<?>[] params = method.getParameterTypes();
    for (int i = 0; i < params.length; i++) {
        System.out.print(params[i].getSimpleName());
        if (i < params.length - 1) System.out.print(", ");
    }
    System.out.println(");");
}

Çıxış:

public void sayHello();

3. Konstruktorlar haqqında məlumatın alınması

Konstruktorlar obyektlərin yaradılması üçün istifadə olunan xüsusi metodlardır.

Metod Nə qaytarır
getConstructors()
Bütün public konstruktorlar
getDeclaredConstructors()
Sinifdə elan edilən bütün konstruktorlar

Nümunə: sinifin bütün konstruktorlarını çıxarırıq

import java.lang.reflect.Constructor;

System.out.println("Constructors:");
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
    System.out.print(clazz.getSimpleName() + "(");
    Class<?>[] params = constructor.getParameterTypes();
    for (int i = 0; i < params.length; i++) {
        System.out.print(params[i].getSimpleName());
        if (i < params.length - 1) System.out.print(", ");
    }
    System.out.println(");");
}

Əgər sinifdə yalnız standart (default) konstruktor elan olunubsa, o da çıxarılacaq.

4. Annotasiyalar: sinifin, metodun və ya sahənin hansı annotasiyalarla işarələndiyini necə bilmək olar

Annotasiyalar siniflərə, metodlara, sahələrə və parametrlərə əlavə edilən xüsusi nişanlardır. Refleksiya vasitəsilə elementdə hansı annotasiyaların olduğunu öyrənmək olar.

Annotasiyaların əldə edilməsi

  • Sinif üçün: clazz.getAnnotations()
  • Metod üçün: method.getAnnotations()
  • Sahə üçün: field.getAnnotations()

Nümunə: @Deprecated annotasiyasının olub-olmadığını yoxlayaq

for (Method method : clazz.getDeclaredMethods()) {
    if (method.isAnnotationPresent(Deprecated.class)) {
        System.out.println(method.getName() + " is @Deprecated");
    }
}

Nümunə: sinifin bütün annotasiyalarını çıxarırıq

for (var annotation : clazz.getAnnotations()) {
    System.out.println(annotation);
}

5. Praktika: sinifin strukturunu təhlil edən mini‑proqram

Gəlin hamısını birləşdirək və sinifin adı veriləndə onun strukturunu: sahələrini, metodlarını, konstruktorlarını və annotasiyalarını çıxaran kiçik bir utilit yazaq.

Kod nümunəsi: ClassInspector

import java.lang.reflect.*;
import java.util.Scanner;

public class ClassInspector {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Sinifin tam adını daxil edin (məsələn, java.util.ArrayList): ");
        String className = scanner.nextLine();

        Class<?> clazz = Class.forName(className);

        System.out.println("\n== Sinif: " + clazz.getName() + " ==");

        // Sinifin annotasiyaları
        System.out.println("Annotasiyalar:");
        for (Annotation annotation : clazz.getAnnotations()) {
            System.out.println("  " + annotation);
        }

        // Sahələr
        System.out.println("\nSahələr:");
        for (Field field : clazz.getDeclaredFields()) {
            System.out.println("  " + Modifier.toString(field.getModifiers())
                    + " " + field.getType().getSimpleName()
                    + " " + field.getName());
        }

        // Metodlar
        System.out.println("\nMetodlar:");
        for (Method method : clazz.getDeclaredMethods()) {
            System.out.print("  " + Modifier.toString(method.getModifiers())
                    + " " + method.getReturnType().getSimpleName()
                    + " " + method.getName() + "(");
            Class<?>[] params = method.getParameterTypes();
            for (int i = 0; i < params.length; i++) {
                System.out.print(params[i].getSimpleName());
                if (i < params.length - 1) System.out.print(", ");
            }
            System.out.println(");");
        }

        // Konstruktorlar
        System.out.println("\nKonstruktorlar:");
        for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
            System.out.print("  " + Modifier.toString(constructor.getModifiers())
                    + " " + clazz.getSimpleName() + "(");
            Class<?>[] params = constructor.getParameterTypes();
            for (int i = 0; i < params.length; i++) {
                System.out.print(params[i].getSimpleName());
                if (i < params.length - 1) System.out.print(", ");
            }
            System.out.println(");");
        }
    }
}

Bu necə işləyir?

  • İstifadəçi sinifin tam adını daxil edir (məsələn, "java.util.ArrayList" və ya öz sinfini).
  • Proqram sinfi dinamik şəkildə yükləyir və onun annotasiyalarını, sahələrini, metodlarını və konstruktorlarını çıxarır.
  • JDK-nın standart siniflərində sınayın — daxilində nə qədər maraqlı şeyin gizləndiyini görəcəksiniz!

6. Faydalı nüanslar və vizuallaşdırma

Vizual sxem: refleksiya vasitəsilə sinif haqqında nələri öyrənmək olar

graph TD
    A[Class<?>] --> B["getFields/getDeclaredFields"]
    A --> C[getMethods/getDeclaredMethods]
    A --> D[getConstructors/getDeclaredConstructors]
    A --> E[getAnnotations]
    B --> F[Field: tip, ad, modifikatorlar]
    C --> G[Method: qaytarılan tip, parametrlər]
    D --> H[Constructor: parametrlər]
    E --> I["Annotation[]"]

Cədvəl: məlumatı harada axtarmaq olar

Nəyi öyrənmək istəyirik Refleksiya ilə necə əldə etməli
Bütün public sahələr
clazz.getFields()
Bütün elan edilən sahələr
clazz.getDeclaredFields()
Bütün public metodlar
clazz.getMethods()
Bütün elan edilən metodlar
clazz.getDeclaredMethods()
Bütün public konstruktorlar
clazz.getConstructors()
Bütün elan edilən konstruktorlar
clazz.getDeclaredConstructors()
Sinifin annotasiyaları
clazz.getAnnotations()
Metodun/sahənin annotasiyaları
method.getAnnotations(), field.getAnnotations()
Modifikatorlar
Modifier.toString(field.getModifiers())

7. Refleksiya ilə işləyərkən tipik səhvlər

Səhv №1: getFields()getDeclaredFields() qarışdırılır.
Əgər siz private sahələri axtarırsınızsa, getDeclaredFields()-dən istifadə edin, yoxsa getFields()-dən. Birincisi sinifdə elan edilən bütün sahələri qaytarır, ikincisi isə yalnız public sahələri (və miras alınanları!).

Səhv №2: Yoxlanılan (checked) istisnalar işlənmir.
Refleksiya metodlarının bir çoxu istisna atır (məsələn, ClassNotFoundException və ya SecurityException). Onları ya emal etməyi, ya da metodun siqnatürasında elan etməyi unutmayın.

Səhv №3: Giriş modifikatorları nəzərə alınmır.
private sahə və metodlara çıxış yalnız setAccessible(true) çağırıldıqdan sonra mümkündür, əks halda IllegalAccessException olacaq. Nümunə:

Field field = clazz.getDeclaredField("age");
field.setAccessible(true); // private sahəyə çıxışı açırıq
int value = (int) field.get(person);

Səhv №4: Yalnız öz metodlarını/sahələrini görməyi gözləyirlər.
getMethods()getFields() yalnız cari sinifin deyil, bütün üst siniflərin də public üzvlərini qaytarır, Object daxil olmaqla. Əgər yalnız öz yazdıqlarınızı görməyi gözləyirsinizsə, bu sizi təəccübləndirə bilər.

Səhv №5: Annotasiyaların mövcudluğu düzgün yoxlanmır.
Konkret annotasiyanı yoxlamaq üçün isAnnotationPresent()-dən istifadə edin; ehtiyac olmadan annotasiya massivi üzərindən əl ilə keçməyin.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION