Reflektions, Benutzer soll Konstruktor auswählen und Parameter übergeben können

Charlie...

Mitglied
Hallo zusammen,

ich lese schon seit einiger Zeit bei euch mit und brauche nun mal selbst einen Denkanstoß.
Die Aufgabe handelt von Reflektions.
Es soll eine Klasse mit verschiedenen Konstruktoren, also ein Überladener übergeben werden.
Der Benutzer soll sich einen aussuchen und Argumente für die Parameter eingeben dürfen.
Wenn ein Parameter ein Referenztyp ist, wird rekursiv runtergegangen.
Dann wird ein Objekt erzeugt.

Ich komm nicht weiter…???:L
Bitte schaut einmal rein und gebt mir einen Tipp, wo ich ggf. mal was nachlesen könnte oder wie ich am Besten weitermache.

Herzlichen Dank,

Charlie…

Hier meine EingabeKlasse
Java:
import java.util.Scanner;

public class Eingabe {
	
	/**
	 * @return
	 */
	protected static String benutzereingabe() {
		Scanner sc = new Scanner(System.in);
		 System.out.println("Bitte Klasse oder Objekt eingeben: ");
	     String eingabe = sc.next();
		return eingabe;
	}

}

Hier die Starterklasse:
Java:
public class ObjektBrowserStarter {

	/**
	 * @param args
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws InstantiationException 
	 */
	public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InstantiationException {

		String eingabe = Eingabe.benutzereingabe();

		Class<?> theClass = Class.forName(eingabe);		

		ObjektBrowser.getOurConstructors(theClass);
		
		Object o= ObjektBrowser.theNewinstance(theClass);

		ObjektBrowser.getOurMethods(theClass);
		
		ObjektBrowser.getOurFields(theClass, o);

	}

}


Und hier die Anwedung:
Java:
public class ObjektBrowser<theClass> {

	/**
	 
	 * @throws IOException
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */

	/**
	 * @param theClass
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */

	protected static Object theNewinstance(Class<?> theClass)
			throws InstantiationException, IllegalAccessException {
		
		Object obj = theClass.newInstance();
		return obj;

	}

	protected static void getOurMethods(Class<?> theClass) {
		Method[] methoden = theClass.getMethods();
		for (Method method : methoden) {
			System.out.println("Methode: " + method);
			/**
			 * TODO hier muss eine Abfrage herein, ob eine Methode ausgeführt
			 * werden soll. Aufgabentext: "Der Benutzer kann dann Methoden
			 * ausführen und bekommt das Objekt mit den ggf. veränderten Werten
			 * angezeigt. Wählt er eine Methode mit Rückgabetyp nicht-void aus,
			 * so kann mit dem Ergebnis weitergearbeitet werden."
			 **/

		}
	}

	/**
	 * @param theClass
	 * @return 
	 */
	protected static void getOurConstructors(Class<?> theClass) {
		Constructor<?>[] constructoren = theClass.getConstructors();
		for (Constructor<?> constructor : constructoren) {				
				System.out.println("Konstruktor von " + theClass.getName()
						+ " " + constructor.toString());					
		Object [] param= constructor.getParameterTypes();
			for (Object object : param) {
				System.out.println("Parameter des Konstruktors"+ constructor.getName()+ "  "+ object.toString());
			}
			
		}
		
		
	}

	protected static void getOurFields(Class<?> theClass, Object obj)
			throws IllegalArgumentException, IllegalAccessException {
		Field[] ourFields = theClass.getDeclaredFields();
		for (Field field : ourFields) {
			System.out.println("Name " + field.getName() + " Typ:"
					+ field.getType() + " Sichtbarkeit: "
					+ field.isAccessible());
			field.setAccessible(true);

			/**
			 * TODO Problem hier: Die get() Methode hat ein Objekt als
			 * Parameter. Wir wissen noch nicht welches das sein soll
			 */

			if (field.getType().isPrimitive()
					&& field.getType().equals(Integer.class)) {
				System.out.println(field.get(obj) + "int");
			}
			if (field.getType().isPrimitive()
					&& field.getType() == Double.class) {
				System.out.println(field.get(obj).toString() + "double");
			}
			if (field.getType().isPrimitive() && field.getType() == Long.class) {
				System.out.println(field.get(obj).toString() + "long");

			} else if (field.getType().isArray()) {
				Object array = field.get(obj);
				int length = Array.getLength(array);
				System.out
						.println("Die Länge Ihres Arrays beträgt: "
								+ length
								+ "Elemente. Mehr Informationen sind derzeit leider nicht möglich");
			}
		}
	}

}


Herzlichen Dank nochmal 🙂
 
[c]public class ObjektBrowser<theClass>[/c] ist schonmal Käse. Du wirst alles über Reflection (und mit vielen Casts) machen müssen, da brauchst du keine Generics.

"Die get() Methode hat ein Objekt als Parameter. Wir wissen noch nicht welches das sein soll"

Bei statischen Feldern null, bei Instanz-Membern die Instanz. Wenn ihr also gerade das x-Feld von einem Point habt, muss da ein Point-Objekt übergeben werden.
 
"public class ObjektBrowser<theClass> ist schonmal Käse. Du wirst alles über Reflection (und mit vielen Casts) machen müssen, da brauchst du keine Generics."

Interessante Anmerkung, weil ich dachte, dass Generics eben auch dazu dienen viele Casts zu vermeiden??

"Die get() Methode hat ein Objekt als Parameter. Wir wissen noch nicht welches das sein soll"
Das Objekt ist das von dem ausgewählten Constructor erzeugte

Und die Frage ist ja eben, wie erzeuge ich dieses Objekt.
Hoffe das war jetzt verständlicher?

DANKE
 
> Interessante Anmerkung, weil ich dachte, dass Generics eben auch dazu dienen viele Casts zu vermeiden??

wenn man als Anwender einer Klasse den Typ kennt, List<String>,
sofern aber der Aufrufer die Klasse auch nur als Benutzereingabe hat, hat er keine Verwendung für Generics,

zwingend streichen musst du es vielleicht nicht, aber zumindest dir klar machen warum es da ist,
ob du es bisher schon verwendest

> Und die Frage ist ja eben, wie erzeuge ich dieses Objekt.

an der Stelle des Kommentars im Quellcode scheint das unerheblich, da ist das Objekt schon fertiger Parameter,
erzeugt wird woanders,

die Funktion von getOurConstructors() ist im Moment etwas unklar,
allgemein kannst du, wie du selber schon schreibst, mit ähnlichen Code anhand von Einschränkungen wie Parameter-Anzahl, Datentypen einen passenden Konstruktor auswählen und mit dem ein Objekt erzeugen
 
Also ich würde es so aufbauen:
In getOutConstructors alle Construktoren aussortieren, die Parameter haben die man nicht in der Console eingeben kann, also all bis auf String,int,double,... und deren Arrays und diese Zurückgeben.
Dann würde ich den Benutzer Fragen welche der Konstruktoren er aufrufen möchte (durchnummeriern und Zahl eingeben lassen)
Als letztes würde ich nacheinander jeweils einen Parameter abfragen und in ein Object[] speichern. Das kannst du dann bei newInstance übergeben.
 

Zurück
Oben