Im Rahmen der Entwicklung einer kleinen ScriptEngine benenne ich nachdenklich Java-Methoden. Ein Aufruf durch die Skript-Engine gibt mir das Objekt den Methodennamen und ein Array von Argumenten. Um die Methode aufzurufen, habe ich versucht, sie mit einem Aufruf von Class.getMethod (Name, Argumenttypen) aufzulösen.
Dies funktioniert jedoch nur, wenn die Klassen der Argumente und die von der Methode erwarteten Klassen identisch sind.Aufruf der engsten Anpassungsmethode
Object o1 = new Object();
Object out = System.out;
//Works as System.out.println(Object) is defined
Method ms = out.getClass().getMethod("println",o1.getClass());
Object o2 = new Integer(4);
//Does not work as System.out.println(Integer) is not defined
Method mo = out.getClass().getMethod("println",o2.getClass());
Ich möchte wissen, ob es eine „einfache“ Art und Weise ist die richtige Methode zu erhalten, wenn möglich mit dem engsten fit für die Argumenttypen, oder wenn ich das selbst habe implementieren.
Closest fit wäre:
Object o1 = new Integer(1);
Object o2 = new String("");
getMethod(name, o1.getClass())//println(Object)
getMethod(name, o2.getClass())//println(String)
Update:
Um zu klären, was ich brauche: Das Script Engine ist ein kleines Projekt, das ich in meiner Freizeit schreiben, so dass keine strikt Regeln ich habe, sind Folgen. Also dachte ich, dass das Auswählen von Methoden, die von der Engine aufgerufen werden, genauso wie der Java-Compiler Methoden zur Kompilierzeit auswählt, nur mit dem dynamischen Typ und nicht mit dem statischen Typ des Objekts (mit oder ohne Autobox)
Dies ist, was ich zuerst hoffte, dass die Class.getMethod() lösen würde. Aber die Class.getMethod() benötigt genau die gleichen Klassen wie Argumenttypen, wie die Methode deklariert, und die Verwendung einer Unterklasse führt zu keiner solchen Methode Exception. Dies mag aus guten Gründen geschehen, macht aber die Methode für mich unbrauchbar, da ich nicht im Voraus weiß, welche Argumenttypen passen würden.
Eine Alternative wäre, Class.getMethods() aufzurufen und das zurückgegebene Array zu durchlaufen und zu versuchen, eine passende Methode zu finden. Dies würde jedoch kompliziert sein, wenn ich einfach nicht die erste „gute“ Methode nehmen will, die ich gestoßen, so hoffte ich, dass es eine bestehende Lösung wäre, die zumindest Griffe:
- am nächsten Sitz: Wenn arg.getClass() == Subklasse und Methoden m (Oberklasse), m (Subklasse), dann rufen m (Subklasse)
- variable Argumente: System.out.printf (String, String ...)
Unterstützung für Autoboxing wäre auch nett.
Wenn ein Aufruf nicht aufgelöst werden kann, kann er eine Ausnahme auslösen (ma (String, Object), ma (Objekt, String), args = String, String)
(Wenn Sie es bis hierher geschafft haben, danke, dass Sie sich die Zeit genommen haben lese es :-))
definieren erste strenge Regeln für die „nächste“, dann ist die Umsetzung ein Detail. – Bozho
genau das, worüber ich mich auch wunderte. Aber für alle pedantisch korrekten Antworter, die sagen: "Definiere am nächsten", habe ich einen einfachen: den, den Java normalerweise wählen würde (ich denke beim Klassenladen). –