Heim > 类库下载 > java类库 > Java-Reflexion

Java-Reflexion

高洛峰
Freigeben: 2016-10-17 09:35:04
Original
1640 Leute haben es durchsucht

Der Reflexionsmechanismus der Java-Sprache in Java:

Im laufenden Zustand kann der Java-Reflexionsmechanismus alle Attribute und Methoden jeder Klasse (Klassendatei) kennen Für jedes Objekt können Sie jede seiner Methoden und Eigenschaften aufrufen:

Diese dynamisch erhaltenen Informationen und die kinetische Energie des dynamischen Aufrufs der Methoden des Objekts werden als Reflexionsmechanismus der Java-Sprache bezeichnet.

Die dynamische Erfassung von Informationen in der Klasse ist eine Java-Reflexion, die die Anatomie der Klasse verstehen kann. Einige Anwendungen können keine neuen Objekte erstellen, aber sie können Klassen dynamisch laden, um Klasseninformationen abzurufen.

Java-Reflexion Wie in der Abbildung gezeigt, kann die Class-Klasse ein Bytecode-Dateiobjekt (.class-Datei) beschreiben, genau wie eine Klasse eine Beschreibung eines Objekts ist.

Java-Reflexion//Frühe Tage: Wenn neu, suchen Sie zuerst die Bytecode-Datei der Klasse basierend auf dem Namen der neuen Klasse und laden Sie sie in den Speicher,

//und merge Erstellen Sie das Bytecode-Dateiobjekt und erstellen Sie dann das entsprechende Person-Objekt der Bytecode-Datei.

com.xidian.Person p=new com.xidian.Person();

//Jetzt
String name="com.xidian.Person";
//Datei finden Die Klassendatei wird in den Speicher geladen und ein Klassenobjekt generiert.
Class clazz=Class.forName(name);
//Wie erstelle ich ein Objekt dieser Klasse?
Object obj=clazz.newInstance();

Durch das Laden reflektierender Klassen ist das Formular oberflächlich gesehen komplexer, aber die Skalierbarkeit ist stärker. Früher musste man ein Objekt manuell in der Programmdatei erstellen

Jetzt muss man nur noch eine Zeichenfolge in die Konfigurationsdatei schreiben, um das entsprechende Objekt zu erstellen.

Frage: Mit clazz.newInstance() kann nur der leere Parameterkonstruktor verwendet werden. Was soll ich tun, wenn ich den Parameterlistenkonstruktor verwenden möchte?

/*

* Was soll ich tun, wenn ich das Objekt erhalte, das in der Klasse verkörpert ist, die dem angegebenen Namen entspricht?

*, wenn das Objekt ohne Verwendung des leeren Parameterkonstruktors initialisiert wird?
*
* Da das Objekt über den angegebenen Konstruktor initialisiert wird,
* sollte daher zuerst der Konstruktor abgerufen werden. Dies kann über eine Bytecode-Datei erfolgen.
* Die Methode lautet: getConstructor(parameterTypes)
*
* In der Reflektion sind Konstruktoren, Felder und Methoden allesamt Objekte.
*/

String name="com.xidian.Person";
Class clazz=Class.forName(name);
//Holen Sie sich das angegebene Konstruktorobjekt
Konstruktorkonstruktor =clazz.getConstructor(String.class,int.class); //Alle Datentypen können durch die Bytecode-Datei beschrieben werden.class
//Initialisieren Sie das Objekt über die newInstance-Methode des Konstruktorobjekts.
Object obj=constructor.newInstance("xiaoming",12);

Holen Sie sich den Wert des angegebenen Felds:

//Schulweiter Zugriff auf private Felder untersuchen. Gewalttätiger Zugriff.

field_1.setAccessible(true);


Object obj=clazz.newInstance();
field_1.set(obj,88);

Object o=field_1.get( obj);

System.out.println(o);

Funktion abrufen:

Methode method=clazz.getMethod("show", null); //Methode ohne Parameter abrufen

Object obj=clazz.newInstance();

method.invoke(obj, null);

Method method2=clazz.getMethod("paramMethod" ,String.class,int.class); //Methode mit Parametern, Methodenname, Parameterliste abrufen
Object obj2=clazz.newInstance();
method2.invoke(obj2, "Xiaoqiang",89) ; //invoke: Ruft die zugrunde liegende Methode auf, die durch dieses Methodenobjekt für das angegebene Objekt mit den angegebenen Parametern dargestellt wird.


Anwendung der Reflexion:

Definieren Sie eine Schnittstelle:

Definieren Sie eine Schnittstellenimplementierungsklasse:
package com.xidian;
public interface PCI {
    public void open();
    public void close();
}
Nach dem Login kopieren

Definieren Sie ein Motherboard:
package com.xidian;
public class SoundCard implements PCI{
    
    public void open(){
        System.out.println("sound open");
    }
    
    public void close(){
        System.out.println("sound close");
    }

}
Nach dem Login kopieren

Test:
package com.xidian;
public class Mainboard {
    
    public void run(){
        System.out.println("main run...");
    }    
    public void usePCI(PCI p){
    if(p!=null){
        p.open();
        p.close();
    }
    }
}
Nach dem Login kopieren

Obwohl die Verwendung von Schnittstellen die Kopplung des Programms verringert hat, ist die Skalierbarkeit des Codes nicht gut.
package com.xidian;

public class Test {
    
    public static void main(String[] args){
        Mainboard mb=new Mainboard();
        mb.run();
        mb.usePCI(new SoundCard());      //如果主板需要使用其他设备,必须重新修改代码,传递一个新创建的对象,可扩展性不好。
        
    }
}
Nach dem Login kopieren

Wenn Sie ein Gerät zum Motherboard hinzufügen, aber den Code nicht ändern möchten, verwenden Sie stattdessen Reflection:

Verwenden Sie nicht new, um es zu vervollständigen, sondern rufen Sie nur seine Klasse ab Datei, die die Objekterstellung innerhalb der Aktion implementiert.

Sie sollten .xml für die Konfiguration mit Reflektion verwenden, was genauer ist. Hier verwenden wir das Eigenschaftenobjekt, um dies zu erreichen.

Ändern Sie den Hauptfunktionscode:

Konfigurationsdatei pci.properties: pci1=com.xidian.SoundCard
public class Test {
    
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException{
        Mainboard mb=new Mainboard();
        mb.run();
        //mb.usePCI(new SoundCard());      //如果主板需要使用其他设备,必须重新修改代码,可扩展性不好。
                                               
        File configFile=new File("pci.properties");
        
        Properties prop=new Properties();             //注意是将配置文件放在项目的一级目录下。
        FileInputStream fis=new FileInputStream(configFile);
        
        prop.load(fis);
        
        for(int x=0;x<prop.size();x++){
            String pciName=prop.getProperty("pci"+(x+1));
            Class clazz=Class.forName(pciName);
            PCI p=(PCI)clazz.newInstance();
            mb.usePCI(p);
        }
        
        fis.close();
    }
}
Nach dem Login kopieren

Beim Erweitern des Geräts müssen Sie nur hinzufügen Das Geräteprogramm Nach dem Schreiben kann die Konfigurationsdatei verwendet werden, ohne dass der Hauptprogrammcode geändert werden muss.

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage