Java Reflection: Überprüfung ist Generic Return Type ein Typ von...

slowfly

Erfahrenes Mitglied
Hallo zusammen

Ich habe eine Klasse mit folgender Methode

Code:
public List<SimpleModel> getSimpleModel(){}

SimpleModel erbt von BusinessModel

Ich will jetzt via Reflection herausfinden, ob der Rückgabewert einer Methode "assignableFrom" List<BusinessModel> ist.

Was ich bis jetzt herausgefunden habe, wie ich überprüfen kann, ob ein ReturnType vom Typ "L
Code:
List.class.isAssignableFrom(method.getReturnType())

Ausserdem komme ich an die Typen:
Code:
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
	ParameterizedType paramType = (ParameterizedType) genericReturnType;
	Type[] actualTypeArgs = paramType.getActualTypeArguments();
}

Im actualTypeArgs[0] steht jetzt folgendes drin:
Code:
[interface model.simple.SimpleModel]

Ich kann jetzt zum Beispiel diesen hier machen:
Code:
actualTypeArgs[0] == SimpleModel.class
Das gibt auch true zurück. Nur: ich muss wissen, ob actualTypeArgs[0] in irgend einer Form ein Typ von BusinessModel ist...

Danke und Gruss
slowy
 
Java:
class ShowSuperclasses
{
  public static void main( String[] args )
  {
    printSuperclasses( new javax.swing.JButton() );
  }
  static void printSuperclasses( Object o )
  {
    Class<?> subclass   = o.getClass();
    Class    superclass = subclass.  getSuperclass()  ;
    while ( superclass != null ) {
      String className = superclass.getName();
      System.out.println( className );
      subclass = superclass;
      superclass = subclass.  getSuperclass()  ;
    }
  }
}

aus: http://openbook.galileodesign.de/javainsel5/javainsel21_001.htm

ûnd wenn du dann die superklasse des objektes o hast, ist ein vergleich ob die superklasse dein BusinessModel ist ja kein problem mehr ;)
 
Zuletzt bearbeitet:
Tschö "I2oxxi"

Ja, mit einzelnen Klassen geht das. Aber wie überprüfe ich das ganze mit Generics?

Code:
	public static void test(){
		List<MyButton> myButtons = new ArrayList<MyButton>();

	}
	
	class MyButton extends JButton {

	}

Wie überprüfe ich jetzt in diesem Beispiel, ob "myButtons" vom Typ "List<JButton>" ist?

Um vielleicht etwas auszuholen:
Ich will via Annotations gewisse Methode "Comparable" machen. Comparable insofern, dass ich zwei BusinessObjekte habe und die alten und die neuen Werte zurückgeben kann. Ich will das mit Annotations lösen - also sobald eine Methode eine gewisse Annotation hat, via Reflection den Wert vom alten und vom neuen Business Objekt lesen. Das funktioniert soweit gut, nur bei Listen muss ich vorher überprüfen, ob es vom Typ List<BusinessModel> ist, da ich hier nicht nur "modified" habe, sondern auch "removed" und "added". Das kann ich nur, wenn es vom Typ BusinessModel ist, da ich einen Identifier brauche.

Danke und Gruss
slowy
 
Möhp

*kopf->tisch* Ich habe, glaube ich, eine Lösung. Relativ simpel:
Ich will zwei Listen vergleichen. Wenn ich mindestens ein Objekt in einer der Liste habe, komme ich an den Typ heran, und kann ihn über Class.isAssignableFrom überprüfen, ob er vom Typ BusinessModel ist. Wenn beide Listen leer sind, hat sich sowieso nüx geändert.

Das scheint mir eine "gute" Lösung zu sein. Oder? ^^

Gruss
slowy
 
naja du müsstes halt die elemente aus der liste nehmen oô
Java:
for(MyButton m : mybuttons){
   printSuperclasses(m);
}
kannst die printsuperclasses methode ja bischen umschreiben, das du ne liste mit allen classobjekten der superklassen bekommst. diese liste kannst du dann prüfen, ob eine der class dateien == JButton.class


edit:: hier hab mal was getan, entweder reden wir aneinander vorbei oder du suchst genau das was ich hier verabriziert habe :p
Java:
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;

public class MyButton extends JButton {

	//einfach ne kleine vererbung zur darstellung
	public MyButton(String s) {
		super(s);
	}

	//gibt eigene klasse und alle superklassen in einer liste
	public static List<Class> getSuperclasses(Object o) {
		List<Class> classes = new ArrayList<Class>();
		Class<?> subclass = o.getClass();
		Class superclass = subclass.getSuperclass();
		classes.add(subclass);
		while (superclass != null) {
			classes.add(superclass);
			String className = superclass.getName();
			subclass = superclass;
			superclass = subclass.getSuperclass();
		}
		return classes;
	}
	
	//prüft, ob alle elemente der liste von typ x sind
	public static boolean testClasses(List<Object> data, Class x){
		boolean b1 = true;
		for(Object o : data){
			boolean b2=false;
			List<Class> superclasses = getSuperclasses(o);
			for(Class superclass : superclasses){
				if(superclass==x)
					b2=true;
			}
			if(b2==false)
				b1=false;
		}
		
		return b1;
	}
	
	public static void main(String[] args){
		List<Object> data = new ArrayList<Object>();
		data.add(new JButton("1"));
		data.add(new JButton("2"));
		data.add(new MyButton("3"));
		
		System.out.println("Alle Element JButtons?");
		System.out.println(testClasses(data, JButton.class));
		System.out.println();
		System.out.println("Alle Elemente MyButtons?");
		System.out.println(testClasses(data, MyButton.class));
	}

}

ausgabe:
Code:
Alle Element JButtons?
true

Alle Elemente MyButtons?
false


wenn man will kann man natürlich auch von allen elementen alle superklassen nehmen und so die "tiefste passende" klasse aller objekte zu finden

aber das sollte doch reichen so oder? weil so siehts du ja ob alles irgendwie JButton ist, und wenn alles irgendwie JButton ist kannse die List<Object> ja einfach ummorphen


Edit:: hab hier noch ne andere methode gefunden, hab mal ne frage:
ist die liste, deren generischen typ du kriegen wills, ne klassenvariable? dann würde es gehen

Java:
public class MyClass {
  public List<String> stringList = ...;
}
Field field = MyClass.class.getField("stringList");

Type genericFieldType = field.getGenericType();
    
if(genericFieldType instanceof ParameterizedType){
    ParameterizedType aType = (ParameterizedType) genericFieldType;
    Type[] fieldArgTypes = aType.getActualTypeArguments();
    for(Type fieldArgType : fieldArgTypes){
        Class fieldArgClass = (Class) fieldArgType;
        System.out.println("fieldArgClass = " + fieldArgClass);
    }
}

von http://tutorials.jenkov.com/java-reflection/generics.html

falls das auch nich wirklich was ist was du suchst weiß ich auch nicht, dann müsstest du nochmal ganz genau beschreiben was genu du da vorhast
 
Zuletzt bearbeitet:
Die generischen Typen werden nur beim Kompilieren geprüft. Zur Laufzeit kannst Du nicht überprüfen ob der generische Typ der Liste "BusinessModel" ist.

Die einzige Möglichkeit hier ist über die Liste zu iterieren und mit instanceof abfragen ob das entsprechende Element vom Typ BusinessModel ist.
 
Möhp

Jo, ich habe irgendwie um 17:55 waaay zu lange gearbeitet, und zu heiss war es auch ^^
Einmal drüber schlafen, und schon kann das Hirn wieder arbeiten.

Ich mach's jetzt abgekürzt so:
Code:
// Überprüfen, ob der Rückgabewert vom Typ List ist.
if(List.class.assignableFrom(method.getReturnType()){
  // überprüfen, ob ein Objekt vom Typ BusinessModel ist
  if(BusinessModel.class.isAssignableFrom(list.get(0)){
    // Zwei BusinessModel-Listen vergleichen
  }
}

Besten Dank für eure Antworten =)

Gruss
slowy
 
Zurück