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

Dies ist ein von KI übersetzter Beitrag.

제이온

[Java] Reflection-Konzept und Verwendung

  • Schreibsprache: Koreanisch
  • Referenzland: Alle Länder country-flag

Sprache auswählen

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

Von durumis AI zusammengefasster Text

  • Reflection ist eine API, die es ermöglicht, zur Laufzeit auf Klasseninformationen zuzugreifen und Klassen nach Bedarf zu manipulieren.
  • Mit Reflection können Instanzen von Klassen erstellt und auf Felder und Methoden zugegriffen werden, unabhängig von den Zugriffskontrollmodifizierern. Dies ist besonders nützlich in großen Entwicklungsphasen, wie z. B. in Frameworks, um Abhängigkeiten dynamisch zu verwalten.
  • Es kann jedoch die Kapselung beeinträchtigen und zu Leistungseinbußen führen, daher sollte es nur verwendet werden, wenn dies unbedingt erforderlich ist.

Was ist Reflection?

Reflection ist eine API, die es ermöglicht, Instanzen einer gewünschten Klasse über das Objekt vom Typ Class zu erstellen, das im Heap-Bereich geladen wurde, und auf die Felder und Methoden der Instanz zuzugreifen, unabhängig von den Zugriffskontrollmodifizierern.



Dabei bezieht sich der Begriff "geladene Klasse" auf den Vorgang, in dem der Klassenlader der JVM das Laden der Klassendatei abgeschlossen hat und einObjekt vom Typ Classerstellt, das die Informationen dieser Klasse enthält, und sie im Heap-Bereich des Speichers speichert. Dies unterscheidet sich von den Objekten, die mit dem Schlüsselwort "new" erstellt werden. Wenn Sie das Objekt vom Typ Class nicht verstehen, lesen Sie die JDK-Dokumentation zu java.lang.class.


Verwendung

Bevor Sie Reflection verwenden können, müssen Sie ein Objekt vom Typ Class abrufen, das im Heap-Bereich geladen wurde. Es gibt drei Möglichkeiten, dies zu tun.


  • Abrufen mit Klasse.class
  • Abrufen mit Instanz.getClass()
  • Abrufen mit Class.forName("Klassenname")


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("Das Passwort ist 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("Jayon", 23, "Darath Entwicklung");
        Class memberClass2 = member.getClass();
        System.out.println(System.identityHashCode(memberClass2));

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

// Ausgabe
1740000325
1740000325

Sie können sehen, dass die drei Methoden das gleiche Objekt vom Typ Class zurückgeben. Unabhängig davon, welche Methode Sie verwenden, ist der Hash-Wert der gleiche, daher können Sie ihn je nach Situation entsprechend verwenden.


Jetzt können Sie mit dem abgerufenen Objekt vom Typ Class eine Instanz dieser Klasse erstellen und auf die Felder und Methoden der Instanz zugreifen, unabhängig vom Zugriffskontrollmodifizierer. Lassen Sie uns zunächst eine Instanz dieser Klasse erstellen.


public class Main {

    public static void main(String[] args) throws Exception {
        // Alle Konstruktoren von Member ausgeben
        Member member = new Member();
        Class memberClass = member.getClass();
        Arrays.stream(memberClass.getConstructors()).forEach(System.out::println);

        // Instanz mit dem Standardkonstruktor von Member erstellen
        Constructor constructor = memberClass.getConstructor();
        Member member2 = constructor.newInstance();
        System.out.println("member2 = " + member2);

        // Instanz mit einem anderen Konstruktor von Member erstellen
        Constructor fullConstructor =
            memberClass.getConstructor(String.class, int.class, String.class);
        Member member3 = fullConstructor.newInstance("Jayon", 23, "Darath Entwicklung");
        System.out.println("member3 = " + member3);
    }
}

// Ausgabe
public Member()
public Member(java.lang.String,int,java.lang.String)
member2 = Member{name='null', age=0, hobby='null'}

Mit getConstructor() können Sie den Konstruktor abrufen und mit newInstance() eine Member-Instanz dynamisch erstellen.

Schließlich können wir auf die Felder und Methoden der Instanz zugreifen, unabhängig vom Zugriffskontrollmodifizierer.

public class Main {

    public static void main(String[] args) throws Exception {
        Member member = new Member("Jayon", 23, "Darath Entwicklung");
        Class memberClass = member.getClass();

        // Feldzugriff
        Field[] fields = memberClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.get(member));
        }
        fields[0].set(member, "Jayon2");
        System.out.println(member);

        // Methodenzugriff
        Method speakMethod = memberClass.getDeclaredMethod("speak", String.class);
        speakMethod.invoke(member, "Reflection Test");

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

// Ausgabe
Jayon
23
Darath Entwicklung
Member{name='Jayon2', age=23, hobby='Darath Entwicklung'}
Reflection Test

Mit getDeclaredFileds() können Sie alle Instanzvariablen der Klasse abrufen, mit get() den Wert des Felds zurückgeben und mit set() den Wert des Felds ändern. Beachten Sie, dass Sie, wenn Sie auf ein Feld mit dem Zugriffskontrollmodifizierer "private" zugreifen möchten, setAccessible() mit dem Wert true aufrufen müssen.


Sie können auch Methoden mit getDeclaredMethod() abrufen. Dabei müssen Sie den Namen der Methode und den Typ der Parameter als Argumente übergeben. Auch hier müssen Sie setAccessible() mit dem Wert true aufrufen, wenn Sie auf eine Methode mit dem Zugriffskontrollmodifizierer "private" zugreifen möchten. Schließlich können Sie die Methode mit invoke() aufrufen, die Sie mit der Reflection-API abgerufen haben.


Vor- und Nachteile

  • Vorteile
    • Reflection bietet die Flexibilität, Instanzen von Klassen zur Laufzeit zu erstellen und auf Felder und Methoden zuzugreifen, unabhängig von Zugriffskontrollmodifizierern, um die notwendigen Aufgaben auszuführen.
  • Nachteile
    • Verletzt die Kapselung.
    • Da Instanzen zur Laufzeit erstellt werden, kann der Typ zur Kompilierzeit nicht geprüft werden.
    • Da Instanzen zur Laufzeit erstellt werden, ist es schwierig, den konkreten Ablauf der Ausführung zu ermitteln.
    • Der Zugriff auf Felder und Methoden mit Reflection ist im Allgemeinen langsamer als der direkte Zugriff. (Nicht in allen Fällen ist die Leistung langsamer.)


Gründe für die Verwendung

Mit der Reflection-API können Sie zur Laufzeit auf Klasseninformationen zugreifen und die Klassen nach Ihren Wünschen manipulieren. Sogar Felder und Methoden, die mit dem Zugriffskontrollmodifizierer "private" deklariert wurden, können manipuliert werden. Da dies die Kapselung verletzt, erscheint es als eine Technik, die man vermeiden sollte.


In einer kleinen Konsolenanwendung kann der Entwickler zur Kompilierzeit alle Objekte und Abhängigkeiten erkennen, die im Programm verwendet werden. In einer großen Entwicklung, wie z. B. bei einem Framework, ist es jedoch schwierig, die vielen Objekte und Abhängigkeiten zu erkennen. In diesem Fall kann Reflection verwendet werden, um Klassen dynamisch zu erstellen und Abhängigkeiten zu verknüpfen.


Nehmen Sie zum Beispiel die Bean Factory in Spring. Wenn Sie einfach die Annotationen @Controller, @Service oder @Repository anwenden, erstellt und verwaltet die Bean Factory automatisch die Klassen mit diesen Annotationen. Der Entwickler hat der Bean Factory diese Klassen nie mitgeteilt. Der Grund dafür ist die Verwendung von Reflection. Wenn zur Laufzeit eine Klasse gefunden wird, die diese Annotationen enthält, wird die Instanz dieser Klasse mit Reflection erstellt, die notwendigen Felder injiziert und in der Bean Factory gespeichert.


Natürlich sollte es aufgrund der Verletzung der Kapselung nur in wirklich notwendigen Fällen verwendet werden.


Quelle

제이온
제이온
제이온
제이온
[Effektives Java] Item 1. Statische Fabrikmethoden in Betracht ziehen Statische Fabrikmethoden sind eine flexible und effiziente Möglichkeit, Instanzen zu erstellen, anstatt Konstruktoren zu verwenden. Sie können benannt werden, Instanzen zurückgeben, die bestimmten Bedingungen entsprechen, und die Leistung durch Caching ve

27. April 2024

[Effektives Java] Punkt 5: Verwenden Sie Dependency Injection anstelle von expliziten Ressourcen Wenn eine Klasse von externen Ressourcen abhängt, sollten Singleton- und statische Utility-Klassen vermieden werden. Durch Dependency Injection können Sie die Flexibilität, Wiederverwendbarkeit und Testbarkeit der Klasse verbessern. Die Verwendung des Fac

28. April 2024

[Effektives Java] Artikel 4. Verwenden Sie einen privaten Konstruktor, um die Instanziierung zu verhindern Bei Utility-Klassen, die nur statische Methoden und Felder enthalten, sollten Sie den Zugriffsschutzmodifizierer des Konstruktors auf private setzen, um die Instanziierung zu verhindern. Dadurch wird verhindert, dass Benutzer den Konstruktor für automatis

28. April 2024

[Javascript] Objektstruktur (V8) Das JavaScript-Objekt wird in der V8-Engine je nach Zustand als strukturierte, optimierte Fast-Mode oder als Hashmap-basierter Dictionary-Mode dargestellt. Der Fast-Mode ist schnell, wenn Schlüssel und Werte fast fixiert sind, aber bei der Hinzufügung neu
곽경직
곽경직
곽경직
곽경직
곽경직

18. März 2024

[Nicht-Hauptfach, Überleben als Entwickler] 14. Zusammenfassung der häufigen technischen Vorstellungsgesprächsinhalte für Einsteiger Dieser Leitfaden ist für die Vorbereitung auf technische Vorstellungsgespräche für Einsteiger. Hauptspeicherbereich, Datenstrukturen, RDBMS und NoSQL, prozedurale und objektorientierte Programmierung, Überladen und Überschreiben, Seitenersatzzustände, Pro
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3. April 2024

Konzeptionelles Datenmodellieren Konzeptionelles Datenmodellieren ist der Prozess, Entitäten zu trennen und die Beziehungen zwischen Entitäten in einem ERD darzustellen. Entitäten sind unabhängige Informationseinheiten, und Attribute sind die Daten, die eine Entität besitzt. Ein Bezeichn
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

8. April 2024

[Concurrency] Atomarer Vorgang: Memory Fence und Memory Ordering Dieser Blogbeitrag erklärt, wie bei atomaren Operationen die Reihenfolge im Speicher berücksichtigt wird, und die Bedeutung von Ordering-Optionen. Es werden verschiedene Ordering-Optionen wie Relaxed, Acquire, Release, AcqRel, SecCst erläutert und die Vor
곽경직
곽경직
곽경직
곽경직
곽경직

12. April 2024

Schwierigkeiten bei der Entwicklung der 한국투자증권-API Dieser Blog-Post befasst sich ausführlich mit den Schwierigkeiten, die bei der Entwicklung der 한국투자증권-API aufgetreten sind, sowie mit den entsprechenden Lösungen. Er enthält Erfahrungsberichte und Tipps von Entwicklern zu Themen wie Kontoeröffnung, Übertr
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마

23. April 2024

[Nicht-Fachmann, Überleben als Entwickler] 16. Tipps für die Erstellung eines Portfolios für Einsteiger Ein Einsteigerentwickler (insbesondere Nicht-Fachmann) muss bei der Erstellung eines Portfolios nicht nur die Technologie, sondern auch die entwickelten Dienste oder Funktionen klar erläutern. Zum Beispiel, wenn es sich um ein "Jobsuchenden-Community"-Pro
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3. April 2024