Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Ich habe folgende Frage: Gibt es eine einfache Möglichkeit die Werte von Methodenannotationen zu sortieren?
Konkret möchte ich bei dem folgenden Programmfragment gerne den Rückgabewert der mit dem Argument value annotierten Methoden in der Zielklasse entsprechend dem lexikographischen Wert von value geordnet via Reflection auflisten.
Hat da jemand eine Idee?
Hier der Programmausschnitt:
Java:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Safe$Wert {
String value(); // <---- auf diesem Wert soll die Sortierung erfolgen
}
public class InstantiateClass {
public static void main (String[] args) throws Exception {
Class targetClass = Class.forName(args[0]);
Method[] declaredMethods = targetClass.getDeclaredMethods();
.....
> entsprechend dem lexikographischen Wert von value geordnet
wie wo was häh?
geordnet verlangt mehrere Dinge, gib doch einfach ein Beispiel..
sollen mehrere Methoden einer Klasse nach deren Namen sortiert werden?
dann sortiere das Method[]-Array welches du schon hast, evtl. mit Comparator (nicht bekannt? -> dazu einlesen)
sollen mehrere Methoden einer Klasse nach dem String-Rückgabewert bei testweisen Aufruf sortiert werden?
dann rufe alle Methoden auf, sammle die Rückgabewerte, stecke sie in bestimmte Container zusammen mit Methodenname,
sortierte diese Objekte (in einem Array oder einer Liste) nach dem Rückgabewert, extrahiert am Ende wieder die Methodennamen
du willst das ganz nur fertig in einem API-Aufruf? da kann ich persönlich leider nix nennen
OK das war vielleicht etwas zu wenig an Info.
Anbei die gesamte Klasse:
Java:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.AnnotatedElement;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Safe$Wert {
String value();
}
public class InstantiateClass {
public static void main (String[] args) throws Exception {
Class targetClass = Class.forName(args[0]);
Method[] declaredMethods = targetClass.getDeclaredMethods();
System.out.println("-------------------------------");
System.out.println("Listing of declared methods in " + targetClass + " :");
System.out.println(">> Method names of actual class with fully qualified parameter, exception and return types");
for (int i = 0; i < declaredMethods.length; i++) {
Object obj = targetClass.newInstance();
System.out.println(declaredMethods[i].toString());
System.out.println("decl class : " + declaredMethods[i].getDeclaringClass());
Class evec[] = declaredMethods[i].getExceptionTypes();
for (int j = 0; j < evec.length; j++) {
System.out.println(" exc #" + j + " " + evec[j]);
}
System.out.println("return type : " + declaredMethods[i].getReturnType());
declaredMethods[i].setAccessible(true);
Class pvec[] = declaredMethods[i].getParameterTypes();
if (pvec.length == 0) {
System.out.println("return value is : " + declaredMethods[i].invoke(obj, new Object[0]));
} else {
System.out.println("method needs an argument");
for (int j = 0; j < pvec.length; j++) {
System.out.println(" param #" + j + " " + pvec[j]);
System.out.println("return value is : " + declaredMethods[i].invoke(obj, new Object[1].toString()));
}
}
Annotation[] annotations = declaredMethods[i].getDeclaredAnnotations();
for (Annotation annotation : annotations) {
System.out.println("annotation type : " + annotation.annotationType().getName());
System.out.println("annotation value : " + annotation.toString());
}
System.out.println("************");
}
System.out.println("-------------------------------");
for (int i = 0; i < declaredMethods.length; i++) {
Annotation[] annotations = declaredMethods[i].getDeclaredAnnotations();
for (Annotation annotation : annotations) {
Safe$Wert val = declaredMethods[i].getAnnotation(Safe$Wert.class);
System.out.print(val.value() + " ");
}
}
System.out.println("");
System.out.println("-------------------------------");
}
}
Das liefert auf die Zielklasse angewendet, die folgende Ausgabe:
Listing of declared methods in class Safe :
>> Method names of actual class with fully qualified parameter, exception and return types
private static java.lang.String Safe.m1()
decl class : class Safe
return type : class java.lang.String
return value is : a
annotation type : Safe$Wert
annotation value : @Safe$Wert(value=10)
************
private static java.lang.String Safe.m2()
decl class : class Safe
return type : class java.lang.String
return value is : d
annotation type : Safe$Wert
annotation value : @Safe$Wert(value=1)
************
private static java.lang.String Safe.m3()
decl class : class Safe
return type : class java.lang.String
return value is : d
annotation type : Safe$Wert
annotation value : @Safe$Wert(value=7)
************
private static java.lang.String Safe.m4()
decl class : class Safe
return type : class java.lang.String
return value is : e
annotation type : Safe$Wert
annotation value : @Safe$Wert(value=3)
Nun sollen die Ausgabe-Werte (return value) nach dem annotation value aufsteigend sortiert werden.
Ich glaube ein Comparator ist da ein richtiger Ansatz. Nur wo muss der Comparator eingefügt werden, in @interface?
Ich hoffe, das macht die Sache etwas klarer.
ich verstehe es noch nicht unbedingt, aber ist letztlich egal,
von mir nochmal der handwerkliche Vorschlag, irgendeine automatische Zauber-Sortierung kann ich nicht nennen, was nicht heißen soll dass sie nicht vielleicht existiert,
also manuell:
du hast da in einer Schleife mehrere Ausgabeabschnitte, jeweils mit einer Menge von Strings, auf irgendeine Weise über Reflection bestimmt,
wie schon gesagt: sammle diese zusammengehörigen Informationen, ruhig in einer neuen Klasse mit 2-10 String attributen, was immer du brauchst,
eines der Objekte hat dann 'e' und '@Safe$Wert(value=3)' und weitere Strings, vielleicht die Zahl 3 gleich aus dem String extrahieren wenn nötig,
diese Objekte kommen alle in eine Liste oder ein Array und werden sortiert, bei eigener Klasse kannst du gleich Comparable richtig implementieren, sonst auch Comparator,
wie Sortieren mit Comparable und Co. grundsätzlich funktioniert ist ein Standardkapitel in jedem Lehrbuch, das möchte ich nicht erklären,
sofern du nicht konkrete Fragen hast a la 'bei mir läuft folgender Code mit Comparator und folgender Eingabe, wieso ist Wert x hier vor Wert y es müsste doch .. gelten?'
um eins zumindest klarzustellen:
> Nur wo muss der Comparator eingefügt werden, in @interface?
nein, bei der Sortierung, komplett unabhängig von den Klassen