[Java] Dynamischer Methodenaufruf durch Reflektion des Aufzählungstyps (Aufzählung)

Einführung

Es ist ein Systemreparaturjob, aber seit Java ist es eine Weile her. Die Umgebung ist Java 7.

FugaName1 bis FugaName4 in einer bestimmten Tabellenspalte werden zu FugaName1 bis FugaName50 erweitert. Ich schlug vor, dass es besser ist, eine separate Tabelle zu verwenden, wenn Sie es in diesem Ausmaß erhöhen möchten. In Anbetracht der Verwendungssituation ist es jedoch nicht erforderlich, die Tabellen zu trennen.

Vor der Renovierung

Die folgende Enum-Klasse wurde für die Ausgabe in eine Datei erstellt. Der Konstruktor wurde am 11.06.2017 hinzugefügt.

Aufzählungsklasse


public class Hoge {
    public String no;
    public String fuganame1;
    public String fuganame2;
    public String fuganame3;
    public String fuganame4;
 
    //Konstrukteur
    public Hoge(String _no, HashMap<String, String> resultList) {
        no = _no;
        fuganame1 = resultList.get(dataParams.FugaName1.getColNamePhysical());   
        fuganame2 = resultList.get(dataParams.FugaName2.getColNamePhysical());   
        fuganame3 = resultList.get(dataParams.FugaName3.getColNamePhysical());   
        fuganame4 = resultList.get(dataParams.FugaName4.getColNamePhysical());   
    }

    public enum dataParams{
          No         ("no"        , "No"         , 0)
        , FugaName1  ("fuganame1" , "Fuga Name1" , 1)
        , FugaName2  ("fuganame2" , "Fuga Name2" , 2)
        , FugaName3  ("fuganame3" , "Fuga Name3" , 3)
        , FugaName4  ("fuganame4" , "Fuga Name4" , 4);

        private final String colNamePhysical;   //Physischer Name
        private final String colNameLogical;    //Logischer Name
        private final int colIdx;

        private dataParams( String physical , String logical, int index) {
            colNamePhysical = physical;
            colNameLogical = logical;
            colIdx = index;
        }

        public String getColNamePhysical() {
            return colNamePhysical;
        }
        public String getColNameLogical() {
            return colNameLogical;
        }
        public int getColIdx() {
            return colIdx;
        }
    }
 }

Da es ungefähr vier ist, ist es solide geschrieben.

Wo zu verwenden


String fugaName1 = (String)Hoge.dataParams.FugaName1.getColNamePhysical();
addMap.put(fmColumnName, fugaName1);
resultList.add(addMap);
String fugaName2 = (String)Hoge.dataParams.FugaName2.getColNamePhysical();
addMap.put(fmColumnName, fugaName2);
resultList.add(addMap);
String fugaName3 = (String)Hoge.dataParams.FugaName3.getColNamePhysical();
addMap.put(fmColumnName, fugaName3);
resultList.add(addMap);
String fugaName4 = (String)Hoge.dataParams.FugaName4.getColNamePhysical();
addMap.put(fmColumnName, fugaName4);
resultList.add(addMap);

Experiment

Wenn es noch vier sind, ist es akzeptabel, auch wenn es solide ist, aber ich denke, dass das Schreiben von 50 als Programmierer nicht gut ist, und es scheint, dass es mehrere andere Dinge gibt, die dasselbe tun, also in Zukunft Als ich darüber nachdachte, versuchte ich es mit Nachdenken. Dies ist mein erstes Mal, dass ich Reflection verwende, daher werde ich ein Bestätigungsprogramm erstellen.

Experiment


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {

    public static void main(String []args) {

        Enum<?> clz = Enum.valueOf(Hoge.dataParams.class, "FugaName2");
        Object[] consts = clz.getClass().getEnumConstants();
        Class<?> sub = consts[0].getClass();
        Method mth = sub.getDeclaredMethod("getColNameLogical"); //getColNamePhysical");
        String val = (String) mth.invoke(consts[clz.ordinal()]);

        System.out.println(val); //Ergebnis: Fuga Name2
    }
}

Nach der Renovierung

Für die Enum-Klasse habe ich sie vorerst auf 50 erhöht. In Bezug auf den Verwendungsort entsprach dies der Reflexion.

Wo zu verwenden


Class<?> clz = Hoge.dataParams.class;
Object[] consts = clz.getEnumConstants();
Class<?> sub = consts[0].getClass();

try {
    Method mth = sub.getDeclaredMethod("getColNamePhysical");
    for(int i=1; i<=50; i++){
        Enum<?> v = Enum.valueOf(Hoge.dataParams.class, String.format("FugaName%d", i));
        String fugaName = (String) mth.invoke(consts[v.ordinal()]);
        addMap.put(fmColumnName, fugaName);
        resultList.add(addMap);
    }
} catch (NoSuchMethodException|SecurityException|IllegalAccessException|InvocationTargetException ex) {
    throw ex;
}

Nachtrag 11.06.2017

Ich erhielt einen Kommentar von Herrn saka1029 und lernte, wie man Reflexion verhindert.

Wo zu verwenden


for (Hoge.dataParams v : Hoge.dataParams.values()) {
    if (!v.toString().matches("FugaName\\d+"))
        continue;
    String fugaName = v.getColNamePhysical();
    addMap.put(fmColumnName, fugaName);
    resultList.add(addMap);
}

Im Konstruktor wird getField (Feldname) verwendet, um die Feldvariablen abzurufen. In diesem Fall wird IllegalArgumentException ausgelöst, IllegalAccessException wird hinzugefügt.

Siehe auch: Unterschiede zwischen getFields und getDeclaredFields

Aufzählungsklasse


    //Konstrukteur
    public Hoge(String _no, HashMap<String, String> resultList) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
        no = _no;

        //Gleiches wie unter FugaName1-Mach bis zu 50
        // fuganame1 = resultList.get(dataParams.FugaName1.getColNamePhysical());
        for (Hoge.dataParams v : Hoge.dataParams.values()) {
            String name = v.toString();
            if (!name.matches("FugaName\\d+"))
                continue;
            Field field = this.getClass().getField(name.toLowerCase());
            field.set(this, resultList.get(v.getColNamePhysical()));
        }
    }

In Bezug auf die Java-API-Spezifikation gab es eine Beschreibung, dass die Reihenfolge sicherlich nicht festgelegt wurde. Class#getFields()

Gibt ein Array zurück, das ein Feldobjekt enthält, das alle zugänglichen öffentlichen Felder der Klasse oder Schnittstelle widerspiegelt, die von diesem Klassenobjekt dargestellt werden. Die Elemente im zurückgegebenen Array werden niemals sortiert oder in einer bestimmten Reihenfolge.

Da es nicht möglich ist, Feldinformationen in der Reihenfolge abzurufen, in der Felder mit der Standard-Java-Funktion definiert sind, wird die Reihenfolge mithilfe von Anmerkungen angegeben. Siehe auch: Ausgabefelder in der Reihenfolge des Anmerkungswerts (http://java-beginner.com/practice-print-fields-in-order/)

Schließlich

Es ist mein erstes Mal, dass ich eine umfassende Renovierung mit Java durchführe, sodass es möglicherweise einen besseren Weg gibt.

Referenz

Recommended Posts

[Java] Dynamischer Methodenaufruf durch Reflektion des Aufzählungstyps (Aufzählung)
[Java] [Kotlin] Rufen Sie valueOf und Werte von Enum generisch auf
Vorteile der statischen Java-Methode
Zusammenfassung der von der Spliterator-Merkmalsmethode #java zurückgegebenen Werte
Bildschirmübergang nach Post-Methode [Java]
[Java] Ausgabe von DateTimeFormatter durch FormatStyle
Rufen Sie die Super-Methode in Java auf
Implementierung der Klonmethode für Java Record
Java-Methode
Java (Methode)
Rails enum Präfektur per Pulldown-Methode auswählen
Rufen Sie Java-Methoden aus JavaScript auf, das in Java ausgeführt wird
Suchen Sie Java Enum nach einem anderen Element
[Java] enum (Aufzählungstyp)
Java-Methode
[Java] -Methode
[Java] -Methode
Benennen und rufen Sie in Ruby übergeordnete Klassenmethoden explizit auf
[Android] Rufen Sie Kotlins Standardargumentmethode von Java aus auf
[Java] Behandlung von Java Beans in der Methodenkette
Die Reihenfolge der Java-Methodenmodifikatoren ist festgelegt
Java-Methodenaufruf von RPG (Methodenaufruf in eigener Klasse)
Methodenname der statischen Factory-Methode, die aus Java 8 gelernt wurde
Genauigkeit der Berechnung des Umfangsverhältnisses nach der Monte-Carlo-Methode
[Hinweis] Java: Geschwindigkeit der Verarbeitung der Liste nach Zweck
Informationen zum Aufruf-Timing und zu den Argumenten der addToBackStack-Methode
Methodenname der Methodenkette in Java Builder + α
Ersetzen von Systemumgebungsvariablen durch Reflektion in Java
Temporäres Support-Memo, wenn der Name des Methodenparameters der Java-Klasse nicht durch Reflektion im Eclipse-Plug-In-Projekt abgerufen werden kann
[Java] Ganzzahlige Informationen von Zeichen in der Textdatei, die mit der Methode read () erfasst wurden
Java8-Methodenreferenz
Java Dynamic Proxy
[Java] forEach-Methode
Java8-Methodenreferenz
[Java] Zufällige Methode
[Java] Übersicht über Java
[Java] Split-Methode
[Java] Grundlegende Zusammenfassung von Java, die nicht von Progate abgedeckt wird ~ Teil 1 ~
Aufrufen von Funktionen in großen Mengen mit Java Reflection
Ich möchte eine Methode einer anderen Klasse aufrufen
[Kotlin] Ermittelt den Argumentnamen des Konstruktors durch Reflektion
Zusammenfassung der Revisionen (neue Yuan-Probleme) nach Java-Version
Rufen Sie eine Methode mit Kotlins Rückrufblock von Java aus auf
Vergleichende Studie der von Java 8 unterstützten TLS Cipher Suite
Ich möchte die Hauptmethode mit Reflektion aufrufen
Zusammenfassung der Methoden zum Lesen von Dateien für jedes Java-Dateiformat