Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

Ez egy AI által fordított bejegyzés.

제이온

[Java] Reflection fogalma és használata

  • Írás nyelve: Koreai
  • Referencia ország: Minden ország country-flag

Válasszon nyelvet

  • Magyar
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी

A durumis AI által összefoglalt szöveg

  • A Reflection egy API, amely a futásidő alatt lehetővé teszi a osztályok információinak elérését és a osztályok manipulálását.
  • A reflection segítségével a osztályok példányait létrehozhatjuk, és elérhetjük a mezőket és a metódusokat a hozzáférési módosítók figyelmen kívül hagyásával. Különösen hasznos a keretrendszerekhez hasonló nagy léptékű fejlesztési fázisokban, ahol dinamikusan kell kezelni a függőségi viszonyokat.
  • A kapszulázás megsértését és a teljesítmény csökkenését okozhatja, ezért célszerű csak akkor használni, ha feltétlenül szükséges.

Mi az a reflexió?

A reflexió egy olyan API, amely lehetővé teszi, hogy a heap memóriában betöltött Class típusú objektumok segítségével létrehozzunk egy kívánt osztály példányát, és hozzáférjünk a példány mezőihez és metódusaihoz, függetlenül a hozzáférési módosítókól.



A betöltött osztály azt jelenti, hogy a JVM osztálybetöltője befejezte az osztályfájl betöltését, majd létrehoz egyClass típusú objektumot, amely tartalmazza az osztály információit, és elmenti a heap memóriába. Fontos megjegyezni, hogy ez különbözik a new kulcsszóval létrehozott objektumoktól. Ha nem érti a Class típusú objektumokat, nézze meg a java.lang.class objektumok JDK dokumentációját.


Használati mód

A reflexió használata előtt meg kell szereznünk a heap memóriában betöltött Class típusú objektumot. Ehhez három módszer létezik.


  • A class.class segítségével
  • Az instance.getClass() segítségével
  • A Class.forName("osztálynév") segítségével


public class Member {

    private String name;

    protected int age;

    public String hobby;

    public Member() {
    }

    public Member(String name, int age, String hobby) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
    }

    public void speak(String message) {
        System.out.println(message);
    }

    private void secret() {
        System.out.println("A jelszó 1234.");
    }

    @Override
    public String toString() {
        return "Member{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", hobby='" + hobby + '\'' +
            '}';
    }
}

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        Class memberClass = Member.class;
        System.out.println(System.identityHashCode(memberClass));

        Member member = new Member("Jeyon", 23, "Dará쓰 Development");
        Class memberClass2 = member.getClass();
        System.out.println(System.identityHashCode(memberClass2));

        Class memberClass3 = Class.forName("{csomagnév}.Member");
        System.out.println(System.identityHashCode(memberClass3));
    }
}

// Futtatási eredmény
1740000325
1740000325

Láthatjuk, hogy a Class típusú objektumok mindegyike ugyanaz, függetlenül attól, hogy melyik módszert használjuk. A hash-értékük megegyezik, ezért a helyzetnek megfelelően szabadon választhatunk.


Mostantól a megszerzett Class típusú objektum segítségével létrehozhatunk példányokat az adott osztályból, és hozzáférhetünk a példány mezőihez és metódusaihoz, függetlenül a hozzáférési módosítóktól. Először hozzunk létre egy példányt az adott osztályból.


public class Main {

    public static void main(String[] args) throws Exception {
        // A Member összes konstruktorának kinyomtatása
        Member member = new Member();
        Class memberClass = member.getClass();
        Arrays.stream(memberClass.getConstructors()).forEach(System.out::println);

        // Példány létrehozása a Member alapértelmezett konstruktorával
        Constructor constructor = memberClass.getConstructor();
        Member member2 = constructor.newInstance();
        System.out.println("member2 = " + member2);

        // Példány létrehozása a Member másik konstruktorával
        Constructor fullConstructor =
            memberClass.getConstructor(String.class, int.class, String.class);
        Member member3 = fullConstructor.newInstance("Jeyon", 23, "Dará쓰 Development");
        System.out.println("member3 = " + member3);
    }
}

// Futtatási eredmény
public Member()
public Member(java.lang.String,int,java.lang.String)
member2 = Member{name='null', age=0, hobby='null'}

A getConstructor() segítségével lekérhetjük a konstruktort, a newInstance() segítségével pedig dinamikusan létrehozhatunk egy Member példányt.

Végül hozzáférjünk a példány mezőihez és metódusaihoz, függetlenül a hozzáférési módosítóktól.

public class Main {

    public static void main(String[] args) throws Exception {
        Member member = new Member("Jeyon", 23, "Dará쓰 Development");
        Class memberClass = member.getClass();

        // Mező hozzáférése
        Field[] fields = memberClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.get(member));
        }
        fields[0].set(member, "Jeyon2");
        System.out.println(member);

        // Metódus hozzáférése
        Method speakMethod = memberClass.getDeclaredMethod("speak", String.class);
        speakMethod.invoke(member, "Reflexió teszt");

        Method secretMethod = memberClass.getDeclaredMethod("secret");
        secretMethod.setAccessible(true);
        secretMethod.invoke(member);
    }
}

// Futtatási eredmény
Jeyon
23
Dará쓰 Development
Member{name='Jeyon2', age=23, hobby='Dará쓰 Development'}
Reflexió teszt

A getDeclaredFileds() segítségével lekérhetjük az osztály összes példányváltozóját, a get() segítségével lekérhetjük a mező értékét, a set() segítségével pedig módosíthatjuk a mező értékét. Fontos megjegyezni, hogy a private hozzáférési módosítóval rendelkező mezőkhöz való hozzáféréskor a setAccessible() metódus paramétereként true-t kell átadnunk.


A getDeclaredMethod() segítségével lekérhetjük a metódusokat is. Ekkor meg kell adnunk a metódus nevét és a paraméterek típusát is. Hasonlóképpen, ha private hozzáférési módosítóval rendelkező metódushoz akarunk hozzáférni, a setAccessible() metódus paramétereként true-t kell beállítanunk. Végül az invoke() metódus segítségével meghívhatjuk a reflexió API-val megszerzett metódusokat.


Előnyök és hátrányok

  • Előnyök
    • Rugalmasságot biztosít a futtatás idején az osztályok példányainak létrehozásához, valamint a mezőkhöz és metódusokhoz való hozzáféréshez, függetlenül a hozzáférési módosítóktól.
  • Hátrányok
    • Sérti a kapszulázást.
    • A futtatás idején történik a példányok létrehozása, így a fordítási időben nem ellenőrizhetők a típusok.
    • A futtatás idején történik a példányok létrehozása, így nehéz megérteni a konkrét működési folyamatot.
    • A reflexió használata lassabb, mint a közvetlen mezőkhöz és metódusokhoz való hozzáférés. (Nem minden esetben lassabb.)


Miért használjuk?

A reflexió API lehetővé teszi, hogy futásidőben hozzáférjünk az osztályok adataihoz, és a kívánt módon manipuláljuk az osztályokat. Még a private hozzáférési módosítóval deklarált mezőket és metódusokat is manipulálhatjuk. Ez olyannak tűnik, mint egy olyan technika, amelyet nem szabadna használni, mivel sérti az objektumorientált tervezés egyik alapelvét, a kapszulázást.


Kis méretű konzolos alkalmazásokban a fejlesztő a fordítási időben pontosan tudja, hogy mely objektumokat és függőségeket fogja használni a program. De a keretekhez hasonló nagy léptékű fejlesztések során rengeteg objektum és függőség van, amelyeket nehéz nyomon követni. Ebben az esetben a reflexió segítségével dinamikusan létrehozhatunk osztályokat és építhetünk fel függőségi viszonyokat.


Például a Spring Bean Factory-ban, ha egy osztályhoz hozzáadjuk a @Controller, @Service, @Repository stb. annotációkat, a Bean Factory automatikusan létrehozza és kezeli az adott annotációval ellátott osztályokat. A fejlesztő nem adta meg az osztályokat a Bean Factory-nak, de ez azért lehetséges, mert a reflexiót használják. Futásidőben megkeresi az annotált osztályokat, és ha talál egyet, a reflexió segítségével létrehozza az osztály példányát, befecskendezi a szükséges mezőket, és elmenti a Bean Factory-ba.


Természetesen, ahogy azt korábban is említettük, a kapszulázás megsértése miatt csak akkor szabad használni, ha feltétlenül szükséges.


Forrás

제이온
제이온
제이온
제이온
[Hatékony Java] 4. elem: Ha meg szeretné akadályozni az instancíázást, használjon privát konstruktort A csak statikus metódusokat és mezőket tartalmazó segédprogram-osztályok esetében célszerű a konstruktort priváttá tenni, hogy megakadályozzák az instancíázást. Ez megakadályozza, hogy a felhasználók automatikusan generáltnak gondolják a konstruktort, és

2024. április 28.

[Hatékony Java] 6. pont: Kerülje a felesleges objektum létrehozását Útmutató a Java-ban a felesleges objektum létrehozásának minimalizálásához. A String, Boolean és egyéb immutabilis objektumok esetében célszerű literálokat használni, míg a reguláris kifejezéseknél a Pattern példányokat érdemes gyorsítótárazni. Emellett a

2024. április 28.

[Hatékony Java] 2. elem: Ha a konstruktornak sok paramétere van, fontolja meg a Builder használatát Ha sok paraméterrel rendelkező objektumot hoz létre, a Builder minta használata segít a kód tisztabb és olvashatóbb megírásában. A kötelező paraméterekkel hozzon létre egy Builder objektumot, a setter metódusokkal állítsa be a választható paramétereket, m

2024. április 27.

[Javascript] Az objektum szerkezete (V8) A JavaScript objektumok a V8 motorban a gyors módnak megfelelő szerkezetek szövegéhez optimalizálódnak, vagy szótár módként működnek hash-táblaként, a állapottól függően. A gyors mód gyors, de ha új kulcsot adnak hozzá, vagy elemet törölnek, a szótár módb
곽경직
곽경직
곽경직
곽경직
곽경직

2024. március 18.

[Nem informatikai szakember, de fejlesztőként akarok túlélni] 14. Gyakran feltett technikai interjúkérdések összefoglalása kezdő fejlesztők számára Útmutató a kezdő fejlesztők számára a technikai interjúra való felkészüléshez. A fő memóriaterület, adatstruktúrák, RDBMS és NoSQL, eljárási és objektumorientált, átírás és túlterhelés, oldalcserélő algoritmusok, folyamatok és szálak, OSI 7-réteg, TCP és
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

2024. április 3.

Koncepcionális adatmodellezés A koncepcionális adatmodellezés az entitások elkülönítésének és az entitások közötti kapcsolatok ERD-ként való ábrázolásának folyamata. Az entitások független információs egységek, az attribútumok pedig az entitások által birtokolt adatok. Az azonosítók e
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

2024. április 8.

[Nem informatikai szakemberként való túlélés fejlesztőként] 16. Szakmai tippek kezdő fejlesztők portfóliójához A kezdő fejlesztőknek (különösen a nem informatikai szakembereknek) a portfólió elkészítése során nemcsak a technológiákat, hanem a fejlesztett szolgáltatásokat vagy funkciókat is világosan le kell írniuk. Például egy "munkakereső közösség" projekt esetén
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

2024. április 3.

[Nem szakmai, fejlesztőként túlélés] 13. Újonc fejlesztő technikai interjú Bemutatjuk a 7 leggyakoribb kérdést, amelyeket az újonc fejlesztő technikai interjúin feltesznek, valamint a felkészülésre vonatkozó tippeket. Tekintsük át az OOP, az adatbázisok, a hálózatok, az algoritmusok és más területekhez kapcsolódó kérdéseket és v
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

2024. április 1.

Nyílt forráskódú AI teljes verem Az AI ökoszisztémában egyre több nyílt forráskódú LLM (nagy nyelvi modell) jelenik meg. Megjelentek a Mistral, a Llama és a phi-2, amelyek erőteljes teljesítményt és nyílt licencet kínálnak, és a használatukhoz számos eszköz is fejlesztés alatt áll. A Lan
RevFactory
RevFactory
RevFactory
RevFactory

2024. február 5.