1. Was ist der Reflexionsmechanismus?
Einfach ausgedrückt bedeutet der Reflexionsmechanismus, dass das Programm während der Ausführung seine eigenen Informationen erhalten kann. Solange in Java der Name der Klasse angegeben ist, können alle Informationen über die Klasse über den Reflexionsmechanismus abgerufen werden.
2. Wo wird der Reflexionsmechanismus eingesetzt?
Manchmal haben wir etwas Wissen verwendet, aber wir kennen die Fachterminologie nicht. Als wir gerade JDBC gelernt haben, haben wir eine Codezeile verwendet, Class.forName("com.mysql.jdbc.Driver.class"). newInstance() ; Zu diesem Zeitpunkt wusste ich jedoch nur, dass diese Codezeile eine Treiberobjektinstanz generierte, und ich kannte ihre spezifische Bedeutung nicht. Nachdem ich mir die Lektion zum Reflexionsmechanismus angehört hatte, wurde mir klar, dass heutzutage viele offene Frameworks Reflexionsmechanismen verwenden.
3. Vor- und Nachteile des Reflexionsmechanismus
Warum einen Reflexionsmechanismus verwenden? Reicht es nicht, Objekte direkt zu erstellen? Dazu gehören die Konzepte von dynamisch und statisch.
Statische Kompilierung: Der Typ wird zur Kompilierzeit bestimmt und das Objekt wird gebunden, also übergeben.
Dynamische Kompilierung: Bestimmen Sie den Typ und binden Sie das Objekt zur Laufzeit. Die dynamische Kompilierung maximiert die Flexibilität von Java, verkörpert polymorphe Anwendungen und reduziert die Kopplung zwischen Klassen.
Kurz gesagt, der Vorteil des Reflexionsmechanismus besteht darin, dass er Objekte dynamisch erstellen und kompilieren kann, was eine große Flexibilität zeigt. Insbesondere bei der Entwicklung von J2EE ist seine Flexibilität sehr offensichtlich. Beispielsweise ist es bei einer umfangreichen Software unmöglich, sie auf einmal perfekt zu entwerfen. Wenn sich herausstellt, dass bestimmte Funktionen aktualisiert werden müssen, können wir den Benutzer nicht auffordern, die vorherigen zu deinstallieren Wenn dies der Fall ist, wird diese Software definitiv nicht von vielen Menschen verwendet. Wenn es statisch ist, muss das gesamte Programm einmal neu kompiliert werden, um die Funktionsaktualisierung zu realisieren. Wenn es den Reflexionsmechanismus verwendet, muss es nicht deinstalliert werden, sondern muss nur zur Laufzeit dynamisch erstellt und kompiliert werden.
Der Nachteil liegt in der Auswirkung auf die Leistung. Die Verwendung von Reflection ist im Grunde eine interpretierte Operation, bei der wir der JVM mitteilen können, was wir tun möchten und die unseren Anforderungen entspricht. Solche Vorgänge sind immer langsamer als die direkte Ausführung desselben Vorgangs.
4. Welche Informationen können mit dem Reflexionsmechanismus gewonnen werden?
Kurz gesagt, es kann alle Informationen abrufen, die in der Klasse vorhanden sind. Voraussetzung ist jedoch, dass der Name der Klasse bekannt ist. Andernfalls sind keine weiteren Informationen verfügbar. Zuerst muss das Klassenobjekt basierend auf dem vollständigen Namen der Klasse erstellt werden kommende Klasse.
Klasse c=Class.forName("className"); Hinweis: className muss der vollständige Name sein, d. h. er muss den Paketnamen enthalten, zum Beispiel cn.netjava.pojo.UserInfo;
Objekt obj=c.newInstance();//Eine Instanz des Objekts erstellen
OK, sobald Sie ein Objekt haben, ist alles einfach zu handhaben. Sie können alle gewünschten Informationen erhalten.
So erhalten Sie den Konstruktor
Konstruktor getConstructor(Class[] params)//Rufen Sie den öffentlichen Konstruktor gemäß den angegebenen Parametern ab
Constructor[] getConstructors()//Alle öffentlichen Konstruktoren abrufen
Konstruktor getDeclaredConstructor(Class[] params)//Rufen Sie öffentliche und nicht öffentliche Konstruktoren basierend auf angegebenen Parametern ab
Constructor[] getDeclaredConstructors()//Alle öffentlichen Konstruktoren abrufen
Methode der Klassenmethode abrufen
Methode getMethod(String name, Class[] params), ruft die Methode basierend auf dem Methodennamen und dem Parametertyp ab
Method[] getMethods()//Alle öffentlichen Methoden abrufen
Methode getDeclaredMethod(String name, Class[] params)// Erhalten Sie je nach Methodenname und Parametertyp öffentliche und nicht öffentliche Methoden
Method[] getDeclaredMethods()//Alle öffentlichen und nicht öffentlichen Methoden abrufen
So erhalten Sie Attribute in einer Klasse
Feld getField(String name)// Rufen Sie die entsprechende öffentliche Variable entsprechend dem Variablennamen ab
Field[] getFields()//Alle öffentlichen Methoden in der Klasse abrufen
Feld getDeclaredField(String name)//Rufen Sie öffentliche und nicht öffentliche Variablen basierend auf dem Methodennamen ab
Field[] getDeclaredFields()//Alle öffentlichen und nichtöffentlichen Methoden in der Klasse abrufen
Dies sind die am häufigsten verwendeten. Wenn Sie diese kennen, ist alles andere einfach zu handhaben ...
5. Was kann man mit dem Reflexionsmechanismus machen?
Als ich anfing, JDBC zu verwenden, musste ich mich übergeben, als ich schrieb, um auf die Datenbank zuzugreifen. Es gab acht Tabellen, und jede Tabelle hatte Hinzufügungs-, Lösch-, Änderungs- und Suchoperationen. Zu diesem Zeitpunkt kannte ich das Konzept nicht Reflexionsmechanismus, also habe ich über verschiedene geschrieben Erstellen Sie verschiedene DAO-Klassen in der Tabelle, was nicht nur die Entwicklung beschleunigt, sondern auch den Code überflüssig macht. Das Schlimmste ist, dass sie fast gleich aussehen und sie dann direkt kopieren und ändern. Da es leicht ist, verschiedene Fehler auf niedriger Ebene zu machen (Groß- und Kleinschreibung, ein weiterer Buchstabe oder ein Buchstabe fehlt ...), kann es lange dauern, einen Fehler zu finden.
Mit dem Java-Reflektionsmechanismus ist alles einfach zu handhaben. Sie müssen lediglich eine Dao-Klasse mit vier Methoden schreiben, sie hinzufügen, löschen, ändern und abfragen. Es ist nicht erforderlich, eine zu erstellen Dao-Klasse für jede Tabelle. Der Reflexionsmechanismus erledigt automatisch den Rest für uns, das ist sein Vorteil. Um es ganz klar auszudrücken: Der Reflexionsmechanismus soll uns dabei helfen, sich wiederholende und regelmäßige Dinge zu erledigen. Daher verwenden viele Softwareprogramme, die automatisch Code generieren, jetzt den Reflexionsmechanismus, um ihn zu vervollständigen. Level-Programmierer sind langsam. Die Langsamen wurden ausgelöscht, warum? Da es nicht nötig ist, Code zu schreiben, kann ihn jeder entwickeln. Warum also tun es Programmierer? Wir haben also nur einen Ausweg, und der besteht darin, hart und noch härter zu arbeiten, ein leitender Programmierer zu werden, sich auf die Entwicklung dummer Software zu spezialisieren und andere Programmierer beiseite zu lassen und sich abzukühlen, haha~
6. Beispiel für die Verwendung des Reflexionsmechanismus zum Hinzufügen und Überprüfen von Datenbankdaten
Grundprinzip: Nehmen Sie beim Speichern von Daten alle Attributwerte der zu speichernden Objekte heraus, stellen Sie dann die SQL-Anweisung für die Abfrage zusammen und packen Sie alle abgefragten Daten in ein Java-Objekt.
Spielregeln: Es gibt nichts ohne Regeln. Vor allem bei Programmen geht es nicht. Ohne Regeln geht es nicht.
1) Jedes Tabellenobjekt in der Datenbank hat eine Pojo-Klasse und jedes Feld in der Tabelle entspricht einem Attribut in der Pojo-Klasse. Darüber hinaus ist der Name der Pojo-Klasse mit dem Namen der Tabelle identisch, und der Attributname und der Feldname sind identisch. Die Groß- und Kleinschreibung spielt keine Rolle, da die Datenbank im Allgemeinen nicht zwischen Groß- und Kleinschreibung unterscheidet.
2) Fügen Sie Standard-Set- und Get-Methoden für jedes Attribut in der Pojo-Klasse hinzu.
Mit den Spielregeln beginnen wir zu spielen.
1. Zunächst gibt es eine Tabelle in der Datenbank. Gehen Sie davon aus, dass der Datenbankname blogsystem lautet und der Tabellenname userinfo lautet. Wie im Bild gezeigt:
2. Erstellen Sie die entsprechende Pojo-Klasse:
Kopieren Sie den Codecode wie folgt:
Paket cn.netjava.pojo;
öffentliche Klasse UserInfo {
private int-id;
privater String-Name;
privater String pwd;
privates Int-Alter;
@Override
öffentlicher String toString() {
return „UserInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", age="
+ Alter + „]“;
}
public int getId() {
Rückgabe-ID;
}
public void setId(int id) {
this.id = id;
}
öffentlicher String getName() {
Rückgabename;
}
public void setName(String name) {
this.name = Name;
}
öffentlicher String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getAge() {
Rückkehralter;
}
public void setAge(int age) {
this.age = Alter;
}
}
2. Schreiben Sie eine Factory-Klasse, um die Datenbankverbindung zu erhalten:
Kopieren Sie den Codecode wie folgt:
Paket cn.netjava.factory;
import java.sql.Connection;
import java.sql.DriverManager;
öffentliche Klasse Connect2DBFactory {
öffentliche statische Verbindung getDBConnection() {
Verbindungsverbindung = null;
versuchen {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/blogsystem";
String user = "root";
String passwort = "netjava";
conn = DriverManager.getConnection(URL, Benutzer, Passwort);
} Catch (Ausnahme e) {
e.printStackTrace();
}
Rücklaufverbindung;
}
}
3. Der Spaß beginnt mit dem Schreiben der Dao-Klasse, die die Datenbank betreibt
Kopieren Sie den Codecode wie folgt:
Paket cn.netjava.session;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
java.util.List importieren;
import cn.netjava.factory.Connect2DBFactory;
import cn.netjava.pojo.UserInfo;
öffentliche Klasse NetJavaSession {
/**
* Analysieren Sie die SQL-Anweisung, die das Objekt speichert
*
* @param-Objekt
*: Objekt, das gespeichert werden muss
* @return: SQL-Anweisung zum Speichern des Objekts
*/
öffentlicher statischer String getSaveObjectSql(Object object) {
//Definieren Sie eine SQL-Zeichenfolge
String sql = „insert into“;
// Holen Sie sich die Klasse des Objekts
Klasse c = object.getClass();
// Alle Methoden im Objekt abrufen
Methode[] methoden = c.getMethods();
// Alle Eigenschaften im Objekt abrufen
Feld[] Felder = c.getFields();
// Den Namen der Objektklasse abrufen
String cName = c.getName();
// Den Tabellennamen aus dem Klassennamen analysieren
String tableName = cName.substring(cName.lastIndexOf(".") + 1,
cName.length());
sql += Tabellenname + "(";
List<String> mList = new ArrayList<String>();
Liste vList = new ArrayList();
for (Methode Methode: Methoden) {
String mName = method.getName();
if (mName.startsWith("get") && !mName.startsWith("getClass")) {
String fieldName = mName.substring(3, mName.length());
mList.add(fieldName);
System.out.println("Feldname----->" + Feldname);
versuchen {
Objektwert = method.invoke(object, null);
System.out.println("Der von der Ausführungsmethode zurückgegebene Wert: " + value);
if (Wertinstanz von String) {
vList.add("/"" + Wert + "/"");
System.out.println("Feldwert------>" + Wert);
} anders {
vList.add(Wert);
}
} Catch (Ausnahme e) {
e.printStackTrace();
}
}
}
for (int i = 0; i < mList.size(); i++) {
if (i < mList.size() - 1) {
sql += mList.get(i) + ",";
} anders {
sql += mList.get(i) + ") Values(";
}
}
for (int i = 0; i < vList.size(); i++) {
if (i < vList.size() - 1) {
sql += vList.get(i) + ",";
} anders {
sql += vList.get(i) + ")";
}
}
return sql;
}
öffentliche statische Liste getDatasFromDB(String tableName, int Id) {
null zurückgeben;
}
/**
* Speichern Sie das Objekt in der Datenbank
*
* @param-Objekt
*: Objekt, das gespeichert werden muss
* @return: Das Ergebnis der Methodenausführung 1: zeigt Erfolg an, 0: zeigt Fehler an
*/
public int saveObject(Object object) {
Verbindungscon = Connect2DBFactory.getDBConnection();
String sql = getSaveObjectSql(object);
versuchen {
// Anweisung Statement=(Anweisung) con.createStatement();
PreparedStatement psmt = con.prepareStatement(sql);
psmt.executeUpdate();
Rückgabe 1;
} Catch (SQLException e) {
e.printStackTrace();
0 zurückgeben;
}
}
/**
* Holen Sie sich das Objekt aus der Datenbank
*
* @param arg0
*: Die Klasse, zu der das Objekt gehört
* @param-ID
*: ID des Objekts
* @return: das zu findende Objekt
*/
öffentliches Objekt getObject(String className, int Id) {
// Den Tabellennamen abrufen
String tableName = className.substring(className.lastIndexOf(".") + 1,
className.length());
//Klassenobjekt basierend auf dem Klassennamen erstellen
Klasse c = null;
versuchen {
c = Class.forName(className);
} Catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
// Füge die Abfrage-SQL-Anweisung zusammen
String sql = "select * from " + tableName + " where Id=" + Id;
System.out.println("SQL-Anweisung finden: " + sql);
// Datenbanklink abrufen
Verbindungscon = Connect2DBFactory.getDBConnection();
//Erstelle eine Instanz der Klasse
Objekt obj = null;
versuchen {
Anweisung stm = con.createStatement();
// Durch Ausführen der Suchanweisung die zurückgegebene Ergebnismenge abrufen
ResultSet set = stm.executeQuery(sql);
// Holen Sie sich das Methodenarray des Objekts
Methode[] methoden = c.getMethods();
// Durchlaufe die Ergebnismenge
while (set.next()) {
obj = c.newInstance();
//Methoden zum Durchqueren von Objekten
for (Methode Methode: Methoden) {
String methodName = method.getName();
// Wenn die Methode des Objekts mit set beginnt
if (methodName.startsWith("set")) {
// Den Namen des Felds in der Datentabelle basierend auf dem Methodennamen abrufen
String ColumnName = methodName.substring(3,
methodName.length());
// Den Parametertyp der Methode abrufen
Class[] parmts = method.getParameterTypes();
if (parmts[0] == String.class) {
// Wenn der Parameter vom Typ String ist, erhalten Sie den entsprechenden Wert aus der Ergebnismenge entsprechend dem Spaltennamen und führen Sie die Set-Methode aus
method.invoke(obj, set.getString(columnName));
}
if (parmts[0] == int.class) {
method.invoke(obj, set.getInt(columnName));
}
}
}
}
} Catch (Ausnahme e) {
e.printStackTrace();
}
return obj;
}
}
4. Wie wäre es mit der Auswirkung des Teststarts:
Kopieren Sie den Codecode wie folgt:
Paket cn.netjava.tester;
import cn.netjava.pojo.UserInfo;
import cn.netjava.session.NetJavaSession;
öffentlicher Klassentester {
public static void main(String args[]) {
//Holen Sie sich das NetJavaSession-Objekt
NetJavaSession session = new NetJavaSession();
//Erstelle ein UserInfo-Objekt
UserInfo user = new UserInfo();
//Legen Sie die Eigenschaften des Objekts fest
user.setId(6988);
user.setAge(44);
user.setPwd("pwd");
user.setName("champion");
//Speichern Sie das Objekt in der Datenbank
String sql = session.getSaveObjectSql(user);
System.out.println("SQL-Anweisung zum Speichern des Objekts: " + sql);
//Objekt finden
UserInfo userInfo = (UserInfo) session.getObject(
"cn.netjava.pojo.UserInfo", 6988);
System.out.println("Erhaltene Informationen: " + userInfo);
}
}
5. Gedruckte Ergebnisse:
7. Fassen wir zusammen
Im Allgemeinen ist der Java-Reflexionsmechanismus eine sehr nützliche Sache. Er kann viele tote Probleme lösen, da der Reflexionsmechanismus sehr flexibel ist und wir nicht zu viel Zeit damit verbringen müssen, den Datenbankcode zu verwenden. Die Methode verbringt mehr Zeit mit den logischen Funktionen des Projekts. Dies kann die Entwicklungszeit erheblich verkürzen und den Code besser lesbar machen. Viele bestehende Open-Source-Frameworks verwenden Reflexionsmechanismen. Sie müssen lediglich Dateien konfigurieren und dann ihre Methoden gemäß den Regeln aufrufen.