Heim  >  Artikel  >  Java  >  Java-Reflexionsmechanismus

Java-Reflexionsmechanismus

高洛峰
高洛峰Original
2016-12-12 11:36:531183Durchsuche

1. Was ist der Reflexionsmechanismus?
Einfach ausgedrückt bedeutet der Reflexionsmechanismus, dass das Programm seine eigenen Informationen erhalten kann, wenn es ausgeführt wird. Solange in Java der Name der Klasse angegeben ist,
Dann können Sie alle Informationen der Klasse über den Reflexionsmechanismus abrufen.
2. Wo man den Reflexionsmechanismus verwendet
Manchmal haben wir etwas Wissen verwendet, aber wir wissen nicht, wie die Fachterminologie lautet. Als wir gerade JDBC gelernt haben, haben wir eine Codezeile verwendet,
Class.forName( "com.mysql.jdbc.Driver.class").newInstance(); Aber zu diesem Zeitpunkt wusste ich nur, dass diese Codezeile eine
-Treiberobjektinstanz generierte, und ich wusste nicht, dass es so war spezifische Bedeutung. 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 den Reflexionsmechanismus verwenden? Reicht es nicht, Objekte direkt zu erstellen? Dies beinhaltet die Konzepte der dynamischen und statischen Kompilierung: Bestimmen Sie den Typ zur Kompilierzeit und binden Sie das Objekt.
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 insbesondere bei der Entwicklung von J2EE eine große Flexibilität zeigt.
Seine Flexibilität ist sehr offensichtlich. Wenn sich beispielsweise herausstellt, dass bestimmte Funktionen aktualisiert werden müssen, können wir Benutzer nicht zur Deinstallation auffordern die vorherigen und dann die neue Version neu installieren. Wenn
so ist, werden nicht viele Leute diese Software verwenden. Wenn es statisch ist, muss das gesamte Programm einmal neu kompiliert werden, um die Aktualisierung der Funktion
zu realisieren. Wenn es den Reflexionsmechanismus verwendet, muss es nicht deinstalliert werden. Es muss nur zur Laufzeit dynamisch erstellt und kompiliert werden um die Funktion zu realisieren.
Ja.
Der Nachteil besteht darin, dass es die Leistung beeinträchtigt. Die Verwendung von Reflection ist im Grunde eine interpretierte Operation. Wir können der JVM mitteilen, was wir tun möchten, und sie
erfüllt unsere Anforderungen. Solche Vorgänge sind immer langsamer als die direkte Ausführung desselben Vorgangs.
4. Welche Informationen können mithilfe des Reflexionsmechanismus erhalten werden? Zunächst muss ein Klassenobjekt basierend auf dem vollständigen Namen der übergebenen Klasse erstellt werden.
Class c=Class.forName("className"); Hinweis: className muss der vollständige Name sein, das heißt, er muss den Paketnamen enthalten, zum Beispiel cn.netjava.pojo.UserInfo; =c.newInstance ();//Eine Instanz des Objekts erstellen
OK, sobald Sie das Objekt haben, ist alles einfach zu erledigen und Sie können alle gewünschten Informationen erhalten.
So erhalten Sie den Konstruktor
Konstruktor getConstructor(Class[] params)//Holen Sie sich den öffentlichen Konstruktor gemäß den angegebenen Parametern

Constructor[] getConstructors()//Holen Sie sich alle öffentlichen Konstruktoren

Konstruktor getDeclaredConstructor(Class[] params)//Öffentliche und nicht öffentliche Konstruktoren gemäß den angegebenen Parametern abrufen

Konstruktor[] getDeclaredConstructors()//Alle öffentlichen Konstruktoren abrufen
Klasse abrufen Methodenmethode

Methode getMethod(String name, Class[] params), Methode entsprechend dem Methodennamen und Parametertyp abrufen

Method[] getMethods()//Alle öffentlichen Methoden abrufen

Methode getDeclaredMethod(String name, Class[] params)//Gemäß Methodenname und Parametertyp öffentliche und nicht öffentliche Methoden abrufen


Method[] getDeclaredMethods()//Alle öffentlichen und nicht öffentlichen Methoden abrufen -öffentliche Methoden
Methoden zum Abrufen von Attributen in der Klasse

Field getField(String name)//Erhalten Sie die entsprechende öffentliche Variable entsprechend dem Variablennamen

Field[] getFields()//Alle abrufen öffentliche Methoden in der Klasse

Feld getDeclaredField(String name)//Rufen Sie öffentliche und nicht öffentliche Variablen entsprechend dem Methodennamen ab

Field[] getDeclaredFields()//Alle öffentlichen und nichtöffentlichen Methoden in der Klasse abrufen
Dies sind die am häufigsten verwendeten Methoden, wenn Sie diese kennen, ist alles andere einfach...
5. Was kann man mit dem Reflexionsmechanismus machen?
Als ich JDBC zum ersten Mal benutzte, musste ich mich übergeben, als ich schrieb, um auf die Datenbank zuzugreifen, und jede Tabelle hatte Vorgänge zum Hinzufügen, Löschen, Ändern und Überprüfen .
Damals wusste ich noch nicht, dass es ein Konzept für einen Reflexionsmechanismus gibt. Deshalb erstellen wir verschiedene Dao-Klassen für verschiedene Tabellen, was nicht nur die Entwicklung beschleunigt, sondern auch den Code
sehr überflüssig macht. Das Schlimmste ist, dass sie fast gleich aussehen und dann direkt kopiert und geändert werden, da leicht alle möglichen Fehler auf niedriger Ebene gemacht werden können (Groß- oder Kleinschreibung, ein
mehr oder ein Buchstabe weniger). .), kann es lange dauern, einen Fehler zu finden.
Mit dem Java-Reflektionsmechanismus ist alles einfach zu handhaben, Sie müssen nur eine Dao-Klasse schreiben, vier Methoden hinzufügen, löschen, ändern und überprüfen und verschiedene Objekte übergeben, und das ist in Ordnung Für jede Tabellen-Dao-Klasse muss eine Tabelle erstellt werden. Der Reflexionsmechanismus erledigt den Rest automatisch für uns. Dies 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, solange Sie die relevanten Parameter gemäß den Regeln eingeben
Warum werden Low-Level-Programmierer langsam ausgelöscht? Da kein Code geschrieben werden muss und jeder ihn entwickeln kann, warum braucht man einen Programmierer? Wir haben also nur einen Ausweg: hart zu arbeiten und hart zu arbeiten, ein leitender Programmierer zu werden, sich auf die Entwicklung von Narrensoftware zu spezialisieren und andere Programmierer beiseite zu lassen und sich abzukühlen, haha ​​~
6. Verwenden Sie den Reflexionsmechanismus, um Datenbankdaten hinzufügen und abfragen Beispiel
Grundprinzip: Nehmen Sie beim Speichern von Daten alle Attributwerte der zu speichernden Objekte heraus und fügen Sie dann die SQL-Anweisung zusammen.
Packen Sie beim Abfragen alle abgefragte Daten in ein Java-Objekt.
Spielregeln: Ohne Regeln gibt es nichts. Besonders bei Programmen geht es nur mit Regeln, aber nicht ohne Regeln.                                                                                   >         1) Jedes Tabellenobjekt in der Datenbank verfügt über eine Pojo-Klasse, und jedes Feld in der Tabelle entspricht einem Attribut in der Pojo-Klasse.
Und der Name der Pojo-Klasse ist derselbe wie der Name der Tabelle, der Attributname und der Feldname sind gleich, die Groß- und Kleinschreibung spielt keine Rolle, da die Datenbank im Allgemeinen nicht zwischen Groß- und Kleinschreibung unterscheidet
2) Hinzufügen Standard-Set- und Get-Methode.
Mit den Spielregeln beginnen wir das Spiel.

1. Nehmen Sie an, dass der Datenbankname blogsystem lautet und einer der Tabellennamen userinfo lautet. Wie im Bild gezeigt:


2. Erstellen Sie die entsprechende Pojo-Klasse:

Java-Reflexionsmechanismus2. Schreiben Sie die Factory-Klasse, um die Datenbankverbindung zu erhalten:

3. Der Spaß beginnt, schreiben Sie die Dao-Klasse, um die Datenbank zu betreiben
package cn.netjava.pojo;
 
public class UserInfo {
private int id;
private String name;
private String pwd;
private int age;
 
@Override
public String toString() {
    return "UserInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", age="
            + age + "]";
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getPwd() {
    return pwd;
}
public void setPwd(String pwd) {
    this.pwd = pwd;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}
 
}

4. Wie wäre es mit der Wirkung des Starts des Tests:
package cn.netjava.factory;
 
import java.sql.Connection;
import java.sql.DriverManager;
 
public class Connect2DBFactory {
    public static Connection getDBConnection() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/blogsystem";
            String user = "root";
            String password = "netjava";
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return conn;
    }
}

5. Die gedruckten Ergebnisse:
package 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;
import java.util.List;
 
import cn.netjava.factory.Connect2DBFactory;
import cn.netjava.pojo.UserInfo;
 
public class NetJavaSession {
    /**
     * 解析出保存对象的sql语句
     *
     * @param object
     *            :需要保存的对象
     * @return:保存对象的sql语句
     */
    public static String getSaveObjectSql(Object object) {
        // 定义一个sql字符串
        String sql = "insert into ";
        // 得到对象的类
        Class c = object.getClass();
        // 得到对象中所有的方法
        Method[] methods = c.getMethods();
        // 得到对象中所有的属性
        Field[] fields = c.getFields();
        // 得到对象类的名字
        String cName = c.getName();
        // 从类的名字中解析出表名
        String tableName = cName.substring(cName.lastIndexOf(".") + 1,
                cName.length());
        sql += tableName + "(";
        List<String> mList = new ArrayList<String>();
        List vList = new ArrayList();
        for (Method method : methods) {
            String mName = method.getName();
            if (mName.startsWith("get") && !mName.startsWith("getClass")) {
                String fieldName = mName.substring(3, mName.length());
                mList.add(fieldName);
                System.out.println("字段名字----->" + fieldName);
                try {
                    Object value = method.invoke(object, null);
                    System.out.println("执行方法返回的值:" + value);
                    if (value instanceof String) {
                        vList.add("\"" + value + "\"");
                        System.out.println("字段值------>" + value);
                    } else {
                        vList.add(value);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        for (int i = 0; i < mList.size(); i++) {
            if (i < mList.size() - 1) {
                sql += mList.get(i) + ",";
            } else {
                sql += mList.get(i) + ") values(";
            }
        }
        for (int i = 0; i < vList.size(); i++) {
            if (i < vList.size() - 1) {
                sql += vList.get(i) + ",";
            } else {
                sql += vList.get(i) + ")";
            }
        }
 
        return sql;
    }
 
    public static List getDatasFromDB(String tableName, int Id) {
 
        return null;
 
    }
 
    /**
     * 将对象保存到数据库中
     *
     * @param object
     *            :需要保存的对象
     * @return:方法执行的结果;1:表示成功,0:表示失败
     */
    public int saveObject(Object object) {
        Connection con = Connect2DBFactory.getDBConnection();
        String sql = getSaveObjectSql(object);
        try {
            // Statement statement=(Statement) con.createStatement();
            PreparedStatement psmt = con.prepareStatement(sql);
            psmt.executeUpdate();
            return 1;
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        }
    }
 
    /**
     * 从数据库中取得对象
     *
     * @param arg0
     *            :对象所属的类
     * @param id
     *            :对象的id
     * @return:需要查找的对象
     */
    public Object getObject(String className, int Id) {
        // 得到表名字
        String tableName = className.substring(className.lastIndexOf(".") + 1,
                className.length());
        // 根据类名来创建Class对象
        Class c = null;
        try {
            c = Class.forName(className);
 
        } catch (ClassNotFoundException e1) {
 
            e1.printStackTrace();
        }
        // 拼凑查询sql语句
        String sql = "select * from " + tableName + " where Id=" + Id;
        System.out.println("查找sql语句:" + sql);
        // 获得数据库链接
        Connection con = Connect2DBFactory.getDBConnection();
        // 创建类的实例
        Object obj = null;
        try {
 
            Statement stm = con.createStatement();
            // 得到执行查寻语句返回的结果集
            ResultSet set = stm.executeQuery(sql);
            // 得到对象的方法数组
            Method[] methods = c.getMethods();
            // 遍历结果集
            while (set.next()) {
                obj = c.newInstance();
                // 遍历对象的方法
                for (Method method : methods) {
                    String methodName = method.getName();
                    // 如果对象的方法以set开头
                    if (methodName.startsWith("set")) {
                        // 根据方法名字得到数据表格中字段的名字
                        String columnName = methodName.substring(3,
                                methodName.length());
                        // 得到方法的参数类型
                        Class[] parmts = method.getParameterTypes();
                        if (parmts[0] == String.class) {
                            // 如果参数为String类型,则从结果集中按照列名取得对应的值,并且执行改set方法
                            method.invoke(obj, set.getString(columnName));
                        }
                        if (parmts[0] == int.class) {
                            method.invoke(obj, set.getInt(columnName));
                        }
                    }
 
                }
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

package cn.netjava.tester;
 
import cn.netjava.pojo.UserInfo;
import cn.netjava.session.NetJavaSession;
 
public class Tester {
    public static void main(String args[]) {
        //获得NetJavaSession对象
        NetJavaSession session = new NetJavaSession();
        //创建一个UserInfo对象
        UserInfo user = new UserInfo();
        //设置对象的属性
        user.setId(6988);
        user.setAge(44);
        user.setPwd("pwd");
        user.setName("champion");
        //将对象保存到数据库中
        String sql = session.getSaveObjectSql(user);
        System.out.println("保存对象的sql语句:" + sql);
        //查找对象
        UserInfo userInfo = (UserInfo) session.getObject(
                "cn.netjava.pojo.UserInfo", 6988);
        System.out.println("获取到的信息:" + userInfo);
 
    }
}

7. Zusammenfassung

Im Allgemeinen ist der Java-Reflexionsmechanismus eine sehr nützliche Sache und kann viele Probleme lösen tote Dinge, da der Reflexionsmechanismus sehr flexibel ist. Dadurch müssen wir nicht zu viel Zeit mit dem Schreiben von Code für den Betrieb der Datenbank verbringen, sondern können mehr Zeit mit den logischen Funktionen des Projekts verbringen. Reduzieren Sie die Entwicklungszeit und machen Sie den Code lesbarer. Viele bestehende Open-Source-Frameworks verwenden Reflexionsmechanismen. Sie müssen lediglich Dateien konfigurieren und dann ihre Methoden gemäß den Regeln aufrufen. Java-Reflexionsmechanismus

Stellungnahme:
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