Nachträgliches Laden einer Klasse.

nitsche

Mitglied
Moinsen,
eine kurze Frage.

Ich habe für ein Spiel diverse eigene ListenerKlassen geschrieben. Diese sind in meinem package soundboard.input.mouse, oder soundboard.input.keyboard etc. etc.

Meine Frage, ob folgendes möglich ist:
Java:
  public Listener createListener(String li_type){
    li_id++;

Listener li_new=(Listener) new  soundboard.input.mouse.MouseListener(so);

abhängig von li_type soll aber die passende klasse dynamisch geladen werden.

Zum Beispiel:

li_type = keyboard -->

Listener li_new = (Listener) new soundboard.input.keyboard.KeyboardListener(so);


li_type = mouse --->

Listener li_new = (Listener) new soundboard.input.mouse.MouseListener(so);


Jemand ne Idee?
 
Wenn Du's so machen willst, wie wär's mit einer Fallunterscheidung?

Wenn alle Listener das Interface Listener implementieren:
Java:
Listener li_new = null;
if (li_type.equals("mouse")
    li_new = new  soundboard.input.mouse.MouseListener(so);
else if (li_type.euqals("keyboard")
    li_new = new  soundboard.input.mouse.KeyboardListener(so);
 
Ich würde auch Refelction vorschlagen. Um den Umgang einfacher zu gestalten, könnte man die vorhandenen Listener-Typen in ein enum verpacken und die createListener-Methode damit arbeiten lassen.

Das Listener-Interface:
Java:
package listener;

public interface ISoundboardListener {

	public void doSomething(ISoundboardEvent event);
}
enum mit den verschiedenen Typen von Listenern:
Java:
package listener;

public enum SoundboardListenerType {

	MOUSE(MouseListener.class),
	KEYBOARD(KeyboardListener.class);

	private Class<? extends ISoundboardListener> listenerClass;

	private SoundboardListenerType(Class<? extends ISoundboardListener> listenerClass) {
		this.listenerClass = listenerClass;
	}

	public Class<? extends ISoundboardListener> getListenerClass() {
		return listenerClass;
	}
}
Methode zum Erzeugen neuer Listener (wichtig: Die Klassen, die das Interface implementieren, müssen in diesem Beispiel einen Konstruktor definieren, der einen String als Argument annimmt):
Java:
package main;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import listener.ISoundboardListener;
import listener.SoundboardListenerType;

public class Main {

	private static int counter = 0;

	public static void main(String[] args) {
		ISoundboardListener[] listeners = new ISoundboardListener[10];
		for (int i = 0; i < listeners.length; i++) {
			listeners[i] = createListener(Math.random() >= 0.5 ? SoundboardListenerType.MOUSE : SoundboardListenerType.KEYBOARD);
		}
		for (ISoundboardListener l: listeners) {
			l.doSomething(null);
		}
	}

	public static ISoundboardListener createListener(SoundboardListenerType type) {
		try {
			Constructor<? extends ISoundboardListener> con = type.getListenerClass().getConstructor(String.class);
			ISoundboardListener listener = con.newInstance(String.valueOf(counter));
			counter++;
			return listener;
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;
	}
}
Die Fehlerbehandlung in createListener fehlt natürlich noch, aber das sollte als Beispiel für ein mögliches Vorgehen ausreichen.
 
Zuletzt bearbeitet von einem Moderator:
warum Reflection wenn alle Klassen schon zur COmpilezeit bekannt ?

ein simples if/else / enum oder was auch immer find ich hier sinnvoller, einfacher und nachvollziehbarer.

Nur wenn die entsprechenden Listener zur Compilezeit nicht existieren, dann bedarf es Reflection
 
Ja, vermutlich ist es auch ein wenig aufgeblasen. Allerdings denke ich, dass es so noch einfacher ist, weitere Listener hinzuzufügen. Wobei der Unterschied nicht gerade groß ist.
So oder so - statt String-Literalen würde ich ein enum verwenden, um die Art des Listeners zu bestimmen. Das verhindert Schreibfehler von vornherein.
 

Zurück
Oben