Zur laufzeit instance einer klasse erzeugen?



  • Hallo, ich möchte zur Laufzeit instanzen einer klasse erzeugen, das ganze soll dazu dienen variable out parameter zu definieren, geht das irgendwie ?

    Mal ein beispiel

    foo( Mytype ... types )
    {
        for ( int i = 0; i < types.length; ++i )
        {
            if ( types[i] == null )
            {
                //hier konkrete instanz erzeugen
                //tue etwas damit
            }
        }
    }
    

    Dann brauch ich nämlich nicht immer instanzierte objekte übergeben weil ich eh nur werte lesen will in der funktion und diese zurück geben will, also ein reiner out parameter. Ich kenne dabei den konkreten typ der klasse aber auch nicht mehr. Das ganze sollte auch so dynamisch sein das ich sobald ich einen neuen typ der vom typ Mytype abgeleitet ist sofort neu instanzieren kann. Ich habe mir schon ne Factory überlegt aber da geht genau das nicht. Da müsste ich zuerst die Classe irgendwie registrieren damit ich davon ne neue instanz erzeugen kann. Ich möchte das einfach für jeden Klassentyp vom typ der von meiner Klasse abgeleitet ist automatisch haben. Geht das irgendwie?


  • Mod

    Kennst Du die prinzipielle Signatur mindestens eines Konstruktors jeder Klasse, die da in Frage kommt?





  • hmm das mit dem reflection könnte mir helfen. Aber wie komme ich von einen objekt zum klassennamen

    als beispiel

    Mytype t = null;

    nun will ich von t den konstruktor aufrufen. aber t.getClass() geht ja nicht. Irgendwie muss ich da aber wohl rankommen.
    Achso den Constructor kenne ich, da alles eh ableitungen von einer basisklasse sind gibts zumindest den standard constructor. Der reicht auch dafür zu.


  • Mod

    Fedaykin schrieb:

    hmm das mit dem reflection könnte mir helfen. Aber wie komme ich von einen objekt zum klassennamen

    als beispiel

    Mytype t = null;

    nun will ich von t den konstruktor aufrufen. aber t.getClass() geht ja nicht. Irgendwie muss ich da aber wohl rankommen.
    Achso den Constructor kenne ich, da alles eh ableitungen von einer basisklasse sind gibts zumindest den standard constructor. Der reicht auch dafür zu.

    1. Konstruktoren werden nicht vererbt. Wenn Deine Basisklasse einen Standardkonstruktor hat, dann heißt das noch lange nicht, dass die abgeleiteten Klassen auch einen haben müssen. Aber ok: Gehen wir mal davon aus, dass Du irgendwo dokumentierst, dass das so sein muss und, dass es auch immer so ist.

    2. Du willst Dir von einem Objekt, das von der Variablen t referenziert wird, die Klasse geben lassen. Das geht natürlich nur, wenn so ein Objekt auch existiert. Du sagst aber gerade schon explizit mit "t = null;", dass es dieses Objekt gar nicht gibt. Wo soll denn dann die Information herkommen? Da muss entweder ein Objekt existieren oder Du musst Dich auf den Typ der Variablen beschränken. In deinem Fall "MyType.class"...oder Du teilst Deiner Methode anders explizit mit, welcher Typ es sein soll. Zum Beispiel mit einem geeigneten Parameter der Klasse Class in der Signatur der Methode.



  • um über reflection ein exemplar einer klasse zu erzeugen, musst das ding entweder einen leeren standardkonstruktor besitzen oder du musst die signatur eines konstruktors kennen.

    das sieht bisschen panne aus, aber reflection wurde mit dem paradigma im hinterkopf geschaffen, dass jede in java geschriebene klasse einen leeren konstruktor besitzt und anschließend über setter befüllt wird.
    das paradigma wurd schon lange über bord geworfen, die reflection api aber nie dahingehend angepasst. im endeffekt muss man aber auch sagen: wie sollte das auch anders möglich sein.

    wenn man reflection verwendet, sollte das schon einen guten grund haben. und in dem fall weiss man auch, dass man nur klassen verwendet, deren signatur man kennt.



  • Gregor schrieb:

    Fedaykin schrieb:

    hmm das mit dem reflection könnte mir helfen. Aber wie komme ich von einen objekt zum klassennamen

    als beispiel

    Mytype t = null;

    nun will ich von t den konstruktor aufrufen. aber t.getClass() geht ja nicht. Irgendwie muss ich da aber wohl rankommen.
    Achso den Constructor kenne ich, da alles eh ableitungen von einer basisklasse sind gibts zumindest den standard constructor. Der reicht auch dafür zu.

    1. Konstruktoren werden nicht vererbt. Wenn Deine Basisklasse einen Standardkonstruktor hat, dann heißt das noch lange nicht, dass die abgeleiteten Klassen auch einen haben müssen. Aber ok: Gehen wir mal davon aus, dass Du irgendwo dokumentierst, dass das so sein muss und, dass es auch immer so ist.

    2. Du willst Dir von einem Objekt, das von der Variablen t referenziert wird, die Klasse geben lassen. Das geht natürlich nur, wenn so ein Objekt auch existiert. Du sagst aber gerade schon explizit mit "t = null;", dass es dieses Objekt gar nicht gibt. Wo soll denn dann die Information herkommen? Da muss entweder ein Objekt existieren oder Du musst Dich auf den Typ der Variablen beschränken. In deinem Fall "MyType.class"...oder Du teilst Deiner Methode anders explizit mit, welcher Typ es sein soll. Zum Beispiel mit einem geeigneten Parameter der Klasse Class in der Signatur der Methode.

    Jo genau dort liegt das problem wie krieg ich den typ raus von t.
    Ich will genau das haben.

    Myclass t=null
    .
    .
    .
    //und hier will ich nun 
    funct( t ) //hier muss irgendwas stehen was mir sagt, MyClass
    

    dort liegt mein problem.


  • Mod

    Fedaykin schrieb:

    Jo genau dort liegt das problem wie krieg ich den typ raus von t.

    Wenn t nicht existiert, dann hat es auch keinen Typ, den Du ermitteln könntest.

    Fedaykin schrieb:

    Ich will genau das haben.

    Myclass t=null
    .
    .
    .
    //und hier will ich nun 
    funct( t ) //hier muss irgendwas stehen was mir sagt, MyClass
    

    dort liegt mein problem.

    Die Klasse MyClass kannst Du allerdings einfach mittels "MyClass.class" im Quellcode angeben.

    thordk schrieb:

    das sieht bisschen panne aus, aber reflection wurde mit dem paradigma im hinterkopf geschaffen, dass jede in java geschriebene klasse einen leeren konstruktor besitzt und anschließend über setter befüllt wird.
    das paradigma wurd schon lange über bord geworfen, die reflection api aber nie dahingehend angepasst. im endeffekt muss man aber auch sagen: wie sollte das auch anders möglich sein.

    Du meinst jetzt nicht direkt Reflection, sondern Java Beans, oder irre ich mich da. IMHO hat Reflection noch anderen Anwendungen neben Java Beans.

    Ich mache zum Beispiel folgendes: Mir ist es relativ egal, wie ein Konstruktor aussieht, ich ermittle einfach zur Laufzeit die Signatur und generiere daraus einen Dialog, der den Nutzer meines Programms in die Lage versetzt, ein entsprechendes Objekt zu erstellen. ...man kann Reflection also auch dann nutzen, wenn man zur Compilezeit die Signatur nicht kennt.



  • hmm ich glaube ich drücke mich etwas unklar aus, ok mal einen wirklich konreten fall

    public class MyBase
    {
    
    }
    
    public class MyClass extends MyBase
    {
    
    }
    
    void foo( MyBase var );
    {
         getType( var ) //jo was isses denn nu genau.
    }
    .
    .
    .
    MyClass myclassvar=null;
    foo( myclassvar );
    

    So ich hoffe das war nun verständlicher. Ansonsten muss halt wirklich der programmierer dafür sorgen das so ein Objekt ordentlich instanziert ist.



  • suchst du

    instanceof
    

    ?



  • nicht wirklich, mit instanceof könnte ich prüfen ob es zu einem mir bekannten klasse gehört. Aber genau das will ich ja auch nicht.

    ich möchte an der mir beschriebenen stelle:

    void foo( MyBase var );
    {
         getType( var ) //jo was isses denn nu genau.
    }
    

    egal welchen objekttyp ich übergebe. Wenn var=null ist ein standard objekt dafür erzeugen (Sofern Standardconstructor verfügbar) ansonsten würde ich eine exception werfen.

    mit instanceof könnte ich ja nur vergleichen ob var von einen mir schon bekannten typ ist. Kurzum ich müsste ein liste mit allen möglichen typen führen mit der ich vergleiche, da wären wir wieder bei einer art Objektfactory. Die nicht wirklich dynamisch ist da ich ja irgendwo mal die klassen in die Fabrik einfügen muss.

    Im grunde will ich nur schauen. Gibt es zu Var einen Standardkonstruktor wenn ja führe diesen aus wenn nicht lass es bleiben. Aber es muss der Standardkonstruktor der eigentlichen Klasse sein von dem Var ist und nicht von der Basisklasse.


  • Mod

    Fedaykin schrieb:

    egal welchen objekttyp ich übergebe. Wenn var=null ist ein standard objekt dafür erzeugen (Sofern Standardconstructor verfügbar) ansonsten würde ich eine exception werfen.

    [...]

    Im grunde will ich nur schauen. Gibt es zu Var einen Standardkonstruktor wenn ja führe diesen aus wenn nicht lass es bleiben. Aber es muss der Standardkonstruktor der eigentlichen Klasse sein von dem Var ist und nicht von der Basisklasse.

    Hast Du eigentlich gelesen, was ich vorhin geschrieben habe? Wenn var==null ist, dann wird über var KEIN Objekt referenziert. Da ist also überhaupt gar kein Objekt, das irgendeinen Typ hat, den man ermitteln kann. Es gibt in diesem Zusammenhang also auch keine "eigentliche Klasse", wie Du es nennst. Da es kein Objekt gibt, das von dieser Klasse ist.



  • Hmm aber ich kenne ja den Variablentyp

    mit

    MyType myvar;

    gebe ich doch an das myvar zumindest von typ MyType sein muss. Ich kann myvar jetzt nicht einfach einen Integer zuweisen oder so. Gut das muss nichts wirklich heißen. Hätte ja sein können das es irgendwas dafür gibt. Also verbuch ichs mal unter nicht möglich.


  • Mod

    Fedaykin schrieb:

    gebe ich doch an das myvar zumindest von typ MyType sein muss. Ich kann myvar jetzt nicht einfach einen Integer zuweisen oder so. Gut das muss nichts wirklich heißen. Hätte ja sein können das es irgendwas dafür gibt. Also verbuch ichs mal unter nicht möglich.

    Naja, was Du machen könntest, wäre natürlich etwas in der Art:

    public Object blah(Class clazz)
    {
       MyClass t = null;
    
       if(t == null)
       {
          t = (MyClass) clazz.newInstance() // usw..
       }
    }
    
    //...
    
    BlahBlahBlah blahblah = (BlahBlahBlah)blah(BlahBlahBlah.class);
    

    Irgendwo musst Du schließlich den Rückgabewert ja vermutlich irgendeiner Variablen zuweisen, die vom Typ Deiner abgeleiteten Klasse ist. Das heißt, Du hast vermutlich eine Stelle, an der Du den genauen Typ kennst. Von der Stelle aus könntest Du den Typ für die Methode bekanntmachen.

    ...wobei ich Deine Verwendung dieses Konstrukts natürlich nur raten kann. Vielleicht solltest Du nochmal etwas zum größeren Kontext Deines Vorhabens sagen.



  • ok der große Kontext meines Vorhabens ist eine vereinfachte form einer db schnittstelle.

    Es gibt eine klasse dbVector. Die ist vom Typ Vector abgeleitet. Hat zwei abstrakte funktionen readValue und writeValue um ihre Werte aus dem Recordset ab zu holen.

    Die eigentlichen vektoren werden davon dann abgleitet. Nun gibts einen IntegerVector der halt integers aus einen Recordset ausliest und sich selber damit befüllt.

    in der eigentlichen db Klasse gibt eine funktion selectRows(String query, dbVector...targets) um die Werte welche ankommen in die Vektoren zu bekommen.

    nun sollte es so laufen das möglich ist

    IntegerVektor myInts=null;
    StringVektor myStrings=null;
    StringVektor myStrings2=null;
    
    int res = db.selectRows("SELECT blah,blub,blub1 FROM mytable;",myInts, myStrings, myStrings2);
    

    hinther hat man halt die Vektoren mit gleicher größe gefüllt mit den konkreten Werten.

    Ich mag halt so ein Cursor handling wie es direkt von jdbc angeboten wird nicht ganz so sehr.

    ich will das ganze noch so erweitern das es sogar möglich ist komplette klassen so zu laden die aus mehreren "Primitiven" bestehen. also prinzip

    MyClassVektor myObjs=null;
    int res = db.selectRows("SELECT myclassvar1, myclassvar2, myclassvar3 FROM myclasstable WHERE blah = 3", myObjs);
    

Anmelden zum Antworten