Variablen Nach Übergabe einer Variable den Constructor aufrufen

ErfinderLabyrinth

Bekanntes Mitglied
Hi,
Ich programmiere gerade ein Spiel und möchte dabei eine Gebäuderegristrierung machen. So etwa:

[CODE lang="java" title="vanilla"]Register.registerObject(?????, "baum");[/CODE]

[CODE lang="java" title="Registrierer"] private static ArrayList<?????> objekte = new ArrayList<>();
private static ArrayList<String> name = new ArrayList<>();
public static void registrierObject(?????, String name) {
?????
Registrierer.objekte.add(?????); // Hier wird es zwischengespeichert
Registrierer.name.add(name);
}
public static List<Task> getObject(String name, List<String> list, String event) { // Zuerst wird in der ArrayList name nach einer Variable , in der das gleiche drinsteht wie in der Variable name, die der Methode übergeben wurde. Danach wird der Construckter mit der Variable list und event ausgeführt und am Schluss wird die Methode getTask ausgeführt, dessen Ergebnis dann returnt wird
?????
return ?????; // return Ergebnis von Baum.getTask
}[/CODE]

[CODE lang="java" title="Object"]
public abstract class Object<T extends Object<?>> { //Weiß nicht, ob ich das <T extends Object<?>> drinlasse
public Object() {
}

abstract public List<Task> getTask();

public void onClick() {

}

public static Object<?> getMethode() {
?????
}
}[/CODE]

[CODE lang="java" title="Baum"] public class Baum extends Object<Baum>{
public Baum(List<String> list, String event) {

}

public List<Task> getTask() {

}
}
[/CODE]

Bei ????? weiß ich nicht weiter

Ziel: in vanilla soll man die Klasse Baum übergeben und im Registrierer sollte man später den Constructor und die getTask Methode öfters aufrufen können( die Variable wird einmalig benutzt d.h. die Variable wird nur kurz aufgerufen und wird danach nie mehr aufgerufen, es werden aber mehrere Variablen von Baum erstellt)

Da man zu dem Spiel später Mods schreiben kann, sollte die Klasse Baum(Objekt kann aber kompliziert sein) und vanilla einfach gehalten werden.

PS: Bei der Klasse Baum wird es später viele ähnliche andere Klassen geben, die alle Registriert werden müssen
 
Nein, einfach erklärt möchte ich in vanilla die Klasse Baum übergeben und die Klasse Regristrierer führt dann den Constructor der übergebenden Klasse aus und erstellt hiermit eine Variable

Da man zu dem Spiel später Mods schreiben kann, sollte die Klasse Baum(Objekt kann aber kompliziert sein) und vanilla einfach gehalten werden.
 
Also eine Methode, die eine Klasse übergeben bekommt und die dann eine Instanz davon erzeugt?

Das wäre dann also etwas in der Art (per Reflection):
Java:
    public static void createInstance(Class<? extends TestInterface> clazz) throws Exception {
        Constructor<? extends TestInterface> constructor = clazz.getConstructor();
        TestInterface instance = constructor.newInstance();
        System.out.println(instance.getClass().getSimpleName());
    }

In dem Code ist dann vorgesehen, dass es etwas wie ein Interface oder eine übergeordnete Klasse gibt, von der alles abgeleitet wurde.
Und dass es einen Konstruktor ohne Parameter gibt.

Testen kann man das z.B. per:
Java:
import java.lang.reflect.Constructor;

public class Main {
    public static void main(String[] args) throws Exception {
        createInstance(TestClass.class);
    }

    public static Number[] test() { return new Double[]{1.0}; }

    public static void createInstance(Class<? extends TestInterface> clazz) throws Exception {
        Constructor<? extends TestInterface> constructor = clazz.getConstructor();
        TestInterface instance = constructor.newInstance();
        System.out.println(instance.getClass().getSimpleName());
    }
}

Java:
public interface TestInterface {
    void someMethod();
}

Java:
public class TestClass implements TestInterface {
    @Override
    public void someMethod() {
        System.out.println("In someMethod!");
    }
}

Die Fehlerbehandlung muss natürlich sinnvoll gebaut werden - da einfach Exception weiter zu reichen ist hier nur gemacht, um den Code ganz kurz zu halten.

Und die Frage nach dem Design muss man immer noch stellen. So ein Design ist oft schlicht nicht notwendig. Also auch wenn es technisch so möglich ist, ist das kein Zeichen, dass es gut ist, etwas so zu machen.
 
Schau Dir doch die verwendeten Methoden an. Die API ist ja gut dokumentiert.

getConstructor und newInstance können beide Argumente bekommen.
 
Statt Reflection bietet sich dafür das Factory Pattern ("abstract factory") an, anstatt die Klasse selbst zu übergeben, übergibst du dann einfach eine Factory, die entsprechende Objekte herstellen kann. damit hast du das ganze dann auch typsicher gelöst.
 
Also eine Methode, die eine Klasse übergeben bekommt und die dann eine Instanz davon erzeugt?

Das wäre dann also etwas in der Art (per Reflection):
Java:
    public static void createInstance(Class<? extends TestInterface> clazz) throws Exception {
        Constructor<? extends TestInterface> constructor = clazz.getConstructor();
        TestInterface instance = constructor.newInstance();
        System.out.println(instance.getClass().getSimpleName());
    }

In dem Code ist dann vorgesehen, dass es etwas wie ein Interface oder eine übergeordnete Klasse gibt, von der alles abgeleitet wurde.
Und dass es einen Konstruktor ohne Parameter gibt.

Testen kann man das z.B. per:
Java:
import java.lang.reflect.Constructor;

public class Main {
    public static void main(String[] args) throws Exception {
        createInstance(TestClass.class);
    }

    public static Number[] test() { return new Double[]{1.0}; }

    public static void createInstance(Class<? extends TestInterface> clazz) throws Exception {
        Constructor<? extends TestInterface> constructor = clazz.getConstructor();
        TestInterface instance = constructor.newInstance();
        System.out.println(instance.getClass().getSimpleName());
    }
}

Java:
public interface TestInterface {
    void someMethod();
}

Java:
public class TestClass implements TestInterface {
    @Override
    public void someMethod() {
        System.out.println("In someMethod!");
    }
}

Die Fehlerbehandlung muss natürlich sinnvoll gebaut werden - da einfach Exception weiter zu reichen ist hier nur gemacht, um den Code ganz kurz zu halten.

Und die Frage nach dem Design muss man immer noch stellen. So ein Design ist oft schlicht nicht notwendig. Also auch wenn es technisch so möglich ist, ist das kein Zeichen, dass es gut ist, etwas so zu machen.
ich habe jetzt 2 Constructor, wie kann ich überprüfen, welcher Constructor ein String braucht?
 
ich habe jetzt 2 Constructor, wie kann ich überprüfen, welcher Constructor ein String braucht?
Ich verstehe gerade die Frage nicht. Wenn Du einen speziellen Konstruktor haben willst, dann kannst Du diesen mit der Methode getConstructor bekommen. Dazu bekommt die Methode ja als Parameter die Typen der gewünschten Parameter.

Wenn Du mit getConstructors Dir alle Konstruktoren übergeben lässt, dann kannst Du für jeden Konstruktor über getTypeParameters abfragen, was für Parameter der jeweilige Konstruktor benötigt.
 
Ich hatte Dir ja schon ein paar Code Bruchstücke gezeigt. Einer davon war:
Java:
    public static void createInstance(Class<? extends TestInterface> clazz) throws Exception {
        Constructor<? extends TestInterface> constructor = clazz.getConstructor();
        TestInterface instance = constructor.newInstance();
        System.out.println(instance.getClass().getSimpleName());
    }

Das getConstructor() hat einen Konstruktor herausgesucht, der keine Parameter benötigt. Die Methode bekommt aber Class<?>... als Parameter, d.h. wenn Du den Konstruktor haben willst, der ein String als Parameter nimmt, dann kannst Du das auch entsprechend aufrufen:
Constructor<? extends TestInterface> constructor = clazz.getConstructor(String.class);

Der Aufruf von newInstance braucht dann natürlich als Parameter auch den String:
TestInterface instance = constructor.newInstance("Test");

Wenn Du nicht gezielt nach einem solchen Konstruktor suchen willst sondern alle Konstruktoren haben willst, dann kannst Du Dir diese per clazz.getConstructors(); geben lassen. Das Array von Constructor kannst Du dann durchgehen um bei jedem nach den benötigten Parametern zu fragen. Was wäre dann in etwa sowas:
Java:
for (Constructor<> constructor : clazz.getConstructors()) {
    Class<?>[] paramTypes = constructor.getTypeParameters();
    // Hier dann machen was immer Du machen willst ...
}
 
Ja, das kommt, wenn man im Forum direkt etwas schreibt. Es kommt natürlich kein Class<?>[] zurück sondern ein TypeVariable<?>[]

Die Code-Abschnitte sind auch nicht als Lösung zum 1:1 kopieren gedacht sondern als grobe Anleitung, wie so etwas gehen könnte um dann z.B. über Google weitere Details heraus zu suchen um alles zu verstehen. Das, was ich hier aufgezeigt habe ist der Bereich Reflection - über dieses Stichwort kannst Du extrem viel im Netz finden.

Aber: Überlege Dir genau, ob Du sowas wirklich brauchst. Die in #7 angesprchenen Factory Pattern sind bestimmt besser geeignet. Reflection wird eher seltener genutzt und ist von der Performance her suboptimal. In der Regel werden für solche Ansprüche andere Wege genutzt wie z.B. ein FactoryPattern.
 
ich denke dass du es über java.lang.properties / und xml oder ähnliches besser lösen kannst da dein Spiel somit nur der Interpreter ist für diese dateien ( auch wenn das mit den konstruktoren funktioniert )

dein Ziel mit den "mods" ist dann erfüllt indem man diese Dateien ändert => somit muss man nicht neu kompilieren und kann alles ändern in den dateien und sas spiel ändert sich dementsprechend
 

Neue Themen


Zurück
Oben