Was ist Java-Reflexion: drei Aspekte von Funktion, Verwendung und Prinzip

Die Java-Reflexion ist einer der fortgeschrittenen Programmierinhalte von Java. Die Beherrschung der Anwendung und des Reflexionsprinzips wird uns helfen, die Funktionsprinzipien einiger Frameworks (Spring) und Plug-Ins (Junit) zu verstehen.

1. Die Rolle der Java-Reflexion

Einfach ausgedrückt hat die Java-Reflexion zwei Hauptfunktionen:

  1. Sorgen Sie dafür, dass Programme dem Switch-Prinzip entsprechen: Entitäten wie Klassen, Module und Funktionen sollten für Erweiterungen offen und für Änderungen geschlossen sein. Benutzer, die sich auf der Plattform des Unternehmens registrieren, benötigen SMS-Bestätigungscodes. Um zu verhindern, dass das Registrierungsgeschäft des Unternehmens aufgrund des Ausfalls der verbundenen SMS-Plattform ausfällt, wird häufig 1+1 für das Failover verwendet. In diesem Fall können Sie Reflektion verwenden, um die Daten in der Datenbank oder im Cache zu lesen und die Plattform zu wechseln, ohne den Geschäftscode zu ändern.

  2. Eine Anwendung entwickeln oder ein Framework entwerfen, ohne die Implementierungsklasse zu kennen: Tatsächlich ähnelt dies ein wenig dem ersten, aber der Programmierer wird zum Benutzer. Die intelligenten Eingabeaufforderungen von IDEA, die XML-Konfiguration von Spring und die Testanmerkungen von Junit nutzen die Reflektion umfassend. Unter normalen Umständen verwenden wir das Schlüsselwort new, um ein Objekt zu instanziieren. Dies ist der Zeitpunkt, an dem die Klasse class angegeben wird. Als Entwickler des Frameworks können sie nicht wissen, welche Klasse der Benutzer (Programmierer) verwendet, welcher Modifikator verwendet wird und wie die Klasse heißt. In diesem Fall spiegelt sich die Rolle der Reflexion wider.

2. Anwendung

1. Schritte zur Verwendung von Reflexion:

  • Apple-Klasse

    public class Apple {
          
          
    	
    	    private int price;
    	
    	    public int getPrice() {
          
          
    	        return price;
    	    }
    	
    	    public void setPrice(int price) {
          
          
    	        this.price = price;
    	    }
    }
    
  • 1. Rufen Sie die Klassenobjektinstanz der Klasse ab

    Class clz = Class.forName("com.zhenai.api.Apple");
    
  • 2. Rufen Sie das Konstruktorobjekt entsprechend der Klassenobjektinstanz ab

    Constructor appleConstructor = clz.getConstructor();
    
  • 3. Verwenden Sie die newInstance-Methode des Constructor-Objekts, um das Reflektionsklassenobjekt abzurufen

    Object appleObj = appleConstructor.newInstance();
    
  • 4. Wenn Sie eine bestimmte Methode aufrufen möchten, müssen Sie zuerst das Objekt abrufen und dann das Objekt verwenden, um die Aufrufmethode aufzurufen:

    Method setPriceMethod = clz.getMethod("setPrice", int.class);
    setPriceMethod.invoke(appleObj, 14);
    
  • Vollständiger Code

    public class Apple {
          
          
    
        private int price;
    
        public int getPrice() {
          
          
            return price;
        }
    
        public void setPrice(int price) {
          
          
            this.price = price;
        }
    
        public static void main(String[] args) throws Exception{
          
          
            //new 关键字实例化
            Apple apple = new Apple();
            apple.setPrice(5); // 调用方法
            System.out.println("Apple Price:" + apple.getPrice());
            //使用反射调用
            Class clz = Class.forName("com.chenshuyi.api.Apple");
            Method setPriceMethod = clz.getMethod("setPrice", int.class);
            Constructor appleConstructor = clz.getConstructor();
            Object appleObj = appleConstructor.newInstance();
            setPriceMethod.invoke(appleObj, 14);  //调用方法
            Method getPriceMethod = clz.getMethod("getPrice");
            System.out.println("Apple Price:" + getPriceMethod.invoke(appleObj));
        }
    }
    
  • Ausgang

    Apple Price:5
    Apple Price:14
    

Bisher konnten wir den grundlegenden Einsatz von Reflexion verstehen. Zusätzlich zu diesen Methoden bietet Java auch andere Reflexions-APIs

2. Die Java-Reflexions-API
ruft das Klassenobjekt in der Reflexion ab. Um in der Reflexion eine Klasse abzurufen oder eine Methode einer Klasse aufzurufen, müssen wir zunächst das Klassenobjekt der Klasse abrufen. In der Java-APIEs gibt drei Möglichkeiten, Klassenobjekte abzurufen:

  • Verwenden Sie zunächst die statische Methode Class.forName. Wenn Sie den vollständigen Pfadnamen der Klasse kennen, können Sie diese Methode verwenden, um das Klassenobjekt abzurufen.

    Class clz = Class.forName("java.lang.String");
    
  • Zweitens verwenden Sie die .class-Methode. Diese Methode eignet sich nur für Klassen, deren Operationen vor der Kompilierung bekannt sind.

    Class clz = String.class;
    
  • Die dritte Möglichkeit besteht darin, die Methode getClass() des Klassenobjekts zu verwenden.

    String str = new String("Hello");
    Class clz = str.getClass();
    

durch ReflexionEs gibt zwei Möglichkeiten, Klassenobjekte zu erstellen:

  • Über die newInstance()-Methode des Class-Objekts.

    Class clz = Apple.class;
    Apple apple = (Apple)clz.newInstance();
    
  • Über die newInstance()-Methode des Constructor-Objekts

    Class clz = Apple.class;
    Constructor constructor = clz.getConstructor();
    Apple apple = (Apple)constructor.newInstance();
    
  • Durch das Erstellen eines Klassenobjekts über das Konstruktorobjekt können Sie eine bestimmte Konstruktionsmethode auswählen, während Sie über das Klassenobjekt nur die standardmäßige Parameterlose Konstruktionsmethode verwenden können. Der folgende Code ruft einen Konstruktor mit Parametern auf, um das Klassenobjekt zu initialisieren.

    Class clz = Apple.class;
    Constructor constructor = clz.getConstructor(String.class, int.class);
    Apple apple = (Apple)constructor.newInstance("红富士", 15);
    

durch ReflexionRufen Sie Klasseneigenschaften, Methoden und Konstruktoren ab::

  • Wir können die Eigenschaften der Class-Klasse über die getFields()-Methode des Class-Objekts abrufen, aber wir können die privaten Eigenschaften nicht abrufen. Und wenn Sie die Methode getDeclaredFields() des Class-Objekts verwenden, können Sie alle Eigenschaften einschließlich privater Eigenschaften abrufen:

    Class clz = Apple.class;
    Field[] fields = clz.getDeclaredFields();
    for (Field field : fields) {
          
          
        System.out.println(field.getName());
    }
    
  • Die Ausgabe ist: Name

Der Preis ist derselbe wie beim Abrufen von Klassenattributen. Wenn wir Klassenmethoden und Klassenkonstruktoren abrufen möchten und private Methoden oder private Konstruktoren erhalten möchten, müssen wir die Methode mit dem deklarierten Schlüsselwort verwenden.

(3) Reflexionsprinzip

Das Reflexionsprinzip stellt im Wesentlichen die Verwendung des objektorientierten Denkens von Java dar. Einfach ausgedrückt behandelt JDK unsere Klasse als Objekt, zerlegt das Objekt in einzelne Attribute und stellt einige Methoden oder Hilfsobjektoperationsattribute bereit. Fügen Sie für die spezifische Analyse einen
bestimmten Link
ein, um Ihr tieferes Verständnis zu gewährleisten.

Abschließend noch die Vor- und Nachteile einer kleinen Reflexion:
Vorteile:

  • Die Instanz der Klasse kann zur Laufzeit dynamisch abgerufen werden, was die Flexibilität und Erweiterbarkeit des Systems erheblich verbessert.
  • In Kombination mit der dynamischen Java-Kompilierung können äußerst leistungsstarke Funktionen realisiert werden.
  • Für Sprachen wie Java, die zuerst kompiliert und dann ausgeführt werden, können wir problemlos flexiblen Code erstellen, der zur Laufzeit zusammengestellt werden kann, ohne Quellcodes zwischen Komponenten zu verknüpfen, was die objektorientierte Implementierung erleichtert.

Mangel:

  • Reflection verbraucht bestimmte Systemressourcen. Wenn Sie also kein Objekt dynamisch erstellen müssen, müssen Sie Reflection nicht verwenden. (Soweit ich weiß, gibt es bereits einige Plug-Ins, die Ressourcenprobleme lindern können.)
  • Die Berechtigungsprüfung kann ignoriert werden, wenn die Methode durch Reflektion aufgerufen wird, und die privaten Methoden und Eigenschaften dieser Klasse können abgerufen werden, sodass die Kapselung der Klasse möglicherweise unterbrochen wird und Sicherheitsprobleme verursacht.

おすすめ

転載: blog.csdn.net/qq_44491709/article/details/114301583