# Generics und instanceof



## The_S (5. Dez 2007)

Hi,

ich habe eine generische Klasse


```
public class MyClass<Cls> {
...
}
```

in dieser Klasse lade ich jetzt über den ClassLoader dynamisch andere Klassen in einer Methode. Diese Methode soll ein true zurückliefern, wenn die dynamisch geladene Klasse vom Typ des Generics ist (bzw. diesen implementiert oder davon erbt). Nur weiß ich nicht, wie ich jetzt überprüfe, ob jetzt genau dieses Zutrifft. Verkürzt sieht das Ganze so aus:


```
public boolean isInstance(String cls, ClassLoader cl) throws 	ClassNotFoundException, 
																						ClassCastException,
																						InstantiationException,
																						IllegalAccessException {
		Class c = cl.loadClass(cls);
		if (c instanceof Cls) {
			return true;
		}
		return false;
	}
```

Nur funktioniert hier instanceof natürlich nicht. Weiß jemand, wie das richtig gemacht wird? Kann ja nicht so schwer sein ...

Danke!


----------



## tfa (5. Dez 2007)

Probier mal:

Class.isAssignableFrom(Class)


----------



## The_S (5. Dez 2007)

Cls cannot be resolved (warum auch immer)!? Bin leider vollkommen neu in der Welt der ClassLoader und Reflection :cry: .


----------



## HoaX (5. Dez 2007)

die generics fliegen beim kompilieren raus. du kannst also zur laufzeit nicht den typ vergleichen. bleibt dir ein objekt oder die klasse direkt als parameter zu übergeben


----------



## The_S (5. Dez 2007)

öhm, anstelle von Generics ein Objekt, oder anstelle von loadClass ein Objekt bzw. eine Klasse übergeben!?


----------



## SlaterB (5. Dez 2007)

anstelle von Generics ein Objekt,
dein Problem ist, dass die Information über den generischen Typ zur Laufzeit nicht mehr vorhanden ist


----------



## The_S (5. Dez 2007)

Richtig, aber ich kann doch einen anderen Programmierer, der meine kleine Klasse verwendet, nicht ernsthaft zumuten, dass er ein Objekt erstellt und mir übergibt. Mal ganz davon abgesehen, dass dann Methoden mit dem Rückgabewert des generischen Typs nicht mehr möglich währen.


----------



## SlaterB (5. Dez 2007)

> dass dann Methoden mit dem Rückgabewert des generischen Typs nicht mehr möglich währen

wieso? der generische Parameter und alles bleibt wie es ist,
nur zusätzlich noch das Objekt ("anstelle von Generics" ist nicht wörtlich gemeint, war eh deine Formulierung  )

ob du dies jemanden zumuten kannst und/ oder willst, ist eine Frage für sich,
ohne wird jedenfalls die Funktionalität nicht gehen
(nach dem bisherigen Wissensstand in diesem Topic)


----------



## The_S (5. Dez 2007)

Hm, ich hab jetzt noch etwas gebaut. Dabei muss nur die Klasse und kein Objekt übergeben werden (was in meinen Augen zumutbar ist). Aber da ich wie gesagt in dem Gebiet recht unerfahren bin, würde ich mich freuen, wenn da noch jemand drüber schaut, der sich damit auskennt (ein erster Test lief bei mir erfolgreich):


```
public class PluginLoader<Cls> {

	private Class gener = null;
	
	public PluginLoader(Class gener) {
		this.gener = gener;
	}

	public boolean isInstance(String cls, ClassLoader cl) throws 	ClassNotFoundException, 
															ClassCastException,
															InstantiationException,
															IllegalAccessException {
		Class c = cl.loadClass(cls);
		Class[] ifaces = c.getInterfaces();
		if (isSubclass(c)) {
			return true;
		}
		for (int i = 0; i < ifaces.length; i++) {
			if (ifaces[i] == gener) {
				return true;
			}
		}
		return false;
	}
	
	public boolean isSubclass(Class c) {
		
		if (c == gener) {
			return true;
		}
		Class cl = c.getSuperclass();
		if (cl == null) {
			return false;
		}
		return isSubclass(cl);
	}
}
```


----------



## SlaterB (5. Dez 2007)

die übergebene Klasse kannst du noch typisieren,
unabhängig von dem verwendeten ClassLoader möchtest du vielleicht das bereits erwähnte isAssignableFrom() verwenden:

```
public class Test
{

    public static void main(String[] args)
        throws Exception
    {
        PluginLoader p = new PluginLoader<Number>(Number.class);
        System.out.println(p.isInstance(String.class.getName()));
        System.out.println(p.isInstance(Number.class.getName()));
        System.out.println(p.isInstance(Integer.class.getName()));
    }
}


class PluginLoader<Cls>
{

    private Class<Cls> gener = null;

    public PluginLoader(Class<Cls> gener)
    {
        this.gener = gener;
    }

    public boolean isInstance(String cls)
        throws Exception
    {
        Class c = Class.forName(cls);
        return gener.isAssignableFrom(c);
    }
}
```


----------



## The_S (5. Dez 2007)

alles klar, funktioniert! Wenn sonst noch wer testen will ...  . Danke!


----------

