WithOne AdventCalendar Dies ist der Artikel am 13. Tag.
In diesem Artikel das Paket "java.lang.reflect". Einführung der sogenannten Reflexion.
Dieses Mal werde ich über "Prirvate" -Methoden und den Zugriff auf Felder schreiben. Es ist einfach, wenn Sie die Reflexion kennen, aber "prirvate = von außen absolut unzugänglich". Es scheint, dass es ziemlich viele Leute gibt, die das denken.
Wenn Sie es nicht wissen, wirkt es sich auf den Fortschritt des Junit-Tests usw. aus, daher werde ich die Methode grob erläutern.
Im Folgenden sind die als Argumente empfangenen Klassen und die Klassen aufgeführt, die die Methoden ausführen.
TestMain.java
public class TestMain {
/**
*Hauptklasse<br>
*Haupt, um etwas zu tun
* @param args Argument
*/
public static void main(String[] args) {
System.out.println("Starten Sie TestMain");
//Das erste Argument ist der Klassenname
String className = args[0];
//Das zweite Argument ist der Methodenname
String methodName = args[1];
try {
//Holen Sie sich Klasse
Class<?> c = Class.forName(className);
System.out.println("Ausführungsklasse:" + c.getName());
//Erstellen Sie eine Instanz
Object o = c.newInstance();
//Methode abrufen
Method m = c.getMethod(methodName);
System.out.println("Ausführungsmethode:" + m.getName());
//Lauf
m.invoke(o);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Beenden Sie TestMain");
}
}
}
Wenn Sie sich das Framework ansehen, scheint es ein Prozess zu sein, der gut geschrieben zu sein scheint. Wenn Sie einen Klassennamen in die Eigenschaftendatei schreiben, ist es in Ordnung, wenn Sie glauben, dass der Prozess wie dieser intern ausgeführt wird.
Lass es uns jetzt laufen lassen.
Wenn Sie die Klasse und Methode festlegen, die Sie im Argument ausführen möchten, und ...
Sie können sehen, dass TestExecute.execute ausgeführt wird.
Aber etwas stimmt nicht. Werfen wir einen Blick auf TestExecute.
TestExecute.java
public class TestExecute {
/**Ausführungsflag*/
private static boolean FLG = true;
/**
*Ausführungsmethode
*/
public void execute() {
System.out.println("Starten Sie TestExecute.execute");
try {
//Ganz egal wie sehr du es versuchst
if (FLG) {
throw new Exception();
}
//Rufen Sie einen Teil des Prozesses auf, den Sie ausführen möchten
prirvateMethod();
}catch (Exception e) {
System.out.println("Fehler aufgetreten!");
} finally {
System.out.println("Beenden Sie TestExecute.execute");
}
}
/**
*Private Methode
*/
private void prirvateMethod() {
//Der Prozess, den Sie ausführen möchten
System.out.println("Führen Sie TestExecute aus.prirvateMethod");
}
}
Da das private Feld "FLG" "wahr" ist, wird es definitiv fehlschlagen. Darüber hinaus scheint der Prozess, den Sie tatsächlich als Kommentar verschieben möchten, "prirvateMethod ()" zu sein.
Lassen Sie uns das ausführen
Lauf!
Sie wurden wütend: "Es gibt keine solche Methode." Nun, es ist privat. Private Methoden sind normalerweise für die Außenwelt unsichtbar und können nicht aufgerufen werden.
Da "java.lang.reflect.Method" eine Klasse zur Steuerung von Methoden ist, kann die Zugriffssteuerung selbstverständlich geändert werden. Um auf privat zuzugreifen, ändern Sie die Quelle wie folgt.
TestMain.java
public class TestMain {
/**
*Hauptklasse<br>
*Haupt, um etwas zu tun
*
* @param args Argument
*/
public static void main(String[] args) {
System.out.println("Starten Sie TestMain");
//Das erste Argument ist der Klassenname
String className = args[0];
//Das zweite Argument ist der Methodenname
String methodName = args[1];
try {
//Holen Sie sich Klasse
Class<?> c = Class.forName(className);
System.out.println("Ausführungsklasse:" + c.getName());
//Erstellen Sie eine Instanz
Object o = c.newInstance();
//Methode abrufen
Method m = c.getDeclaredMethod(methodName);
System.out.println("Ausführungsmethode:" + m.getName());
//Ändern Sie die Methode in zugänglich
m.setAccessible(true);
//Lauf
m.invoke(o);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Beenden Sie TestMain");
}
}
}
"GetMethod" wurde in "getDeclaredMethod" geändert und eine Zeile "m.setAccessible (true)" wurde hinzugefügt. Deklariert bedeutet, dass es deklariert wurde. Wenn Sie es also vorerst schreiben, können Sie es verwenden oder nicht, aber Sie werden es bekommen! Es ist eine Methode namens.
Sie können es mit "getDeclaredMethod" erhalten, Es kann nicht einfach durch Abrufen ausgeführt werden, und "java.lang.IllegalAccessException" tritt wie unten gezeigt auf.
Verwenden Sie daher "setAccessible", um es zwangsweise in einen zugänglichen Zustand zu ändern.
Lassen Sie es uns tatsächlich ausführen.
Sie können sehen, dass die "Prirvate-Methode" ausgeführt wird.
Aber schließlich möchte ich, dass Sie "execute" ausführen, also schreiben wir das Feld "FLG" neu. Das Feld "FLG" ist privat und normalerweise nicht zugänglich. Sie können es jedoch so ändern, dass es wie eine Methode zugänglich ist.
TestMain.java
public class TestMain {
/**
*Hauptklasse<br>
*Haupt, um etwas zu tun
*
* @param args
*Streit
*/
public static void main(String[] args) {
System.out.println("Starten Sie TestMain");
//Das erste Argument ist der Klassenname
String className = args[0];
//Das zweite Argument ist der Methodenname
String methodName = args[1];
try {
//Holen Sie sich Klasse
Class<?> c = Class.forName(className);
System.out.println("Ausführungsklasse:" + c.getName());
//Erstellen Sie eine Instanz
Object o = c.newInstance();
//Feld "FLG" abrufen
Field f = c.getDeclaredField("FLG");
System.out.println("Feld ändern:" + f.getName());
//Zugriff
f.setAccessible(true);
//Wert einstellen
f.set(o, false);
//Methode abrufen
Method m = c.getMethod(methodName);
System.out.println("Ausführungsmethode:" + m.getName());
//Lauf
m.invoke(o);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Beenden Sie TestMain");
}
}
}
Lauf
Sie konnten die "Prirvate-Methode" ausführen, während Sie die "Execute" ausführen.
Das ist alles für die Erklärung dieser Reflexion. War es hilfreich?
Recommended Posts