Zur laufzeit instance einer klasse erzeugen?
-
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.
-
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.
-
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.
-
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);