# objekt einer Klasse erstellen



## vodn7v (20. Feb 2009)

hallo ich möchte zur laufzeit ein objekt einer klasse erstellen.

ich übergebe einer methode den klassennamen (inkl. pfad) einer existierenden klasse. ich weiss halt vorher nicht welche es ist. davon möchte ich gerne ein objekt erstellen damit ich die methoden des klassenobjektes nutzen kann.

wie mach ich sowas am besten ??


danke !!


----------



## Landei (20. Feb 2009)

Kommt drauf an. Hat die Klasse einen öffentlichen, argumentlosen Konstruktor hat, dann etwa so:

```
try {
     Class<?> clazz = Class.forName("java.lang.Date");
     Object o = clazz.newInstance();
     System.out.println(o);
   } catch(Exception ex) {
     ex.printStackTrace(); 
   }
```


----------



## tfa (20. Feb 2009)

Über Reflection: http://java.sun.com/docs/books/tutorial/reflect/index.html

java.lang.Class.newInstance()


----------



## vodn7v (20. Feb 2009)

also ich erstelle mir so erstmal die struktur meiner klasse:

               DBAccess newTableClass = null;
	       Object newObject = null;

		Class c = Class.forName( className );
		newObject  = (Object) c.newInstance();

		newTableClass = (com.test.class.DBAccess) newObject ;

jetzt soll das objekt der klasse die eigenschaften von der klasse DBAccess bekommen.
aber irgednwie hauzt das nicht so recht hin.


----------



## tfa (20. Feb 2009)

> irgednwie hauzt das nicht so recht hin


Ach?

Was steht denn in className? "com.test.class.DBAccess"?


----------



## SlaterB (20. Feb 2009)

'irgednwie' ist dein Posting ungenau
-> die großen drei: Compilerfehler? Exception zur Laufzeit? oder welches andere Fehlverhalten?


----------



## vodn7v (20. Feb 2009)

hallo, ok es war vllt etwas ungenau.. hier nochmal mein code:

			com.org.test.obclass.DBAccess newTableClass = null;
			Object newObject = null;


				Class c = null;
				try {
					c = Class.forName("com.log.lud.sql.IFC_test");
				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					newObject = (Object) c.newInstance();
				} catch (InstantiationException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IllegalAccessException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			 newTableClass = (com.org.test.obclass.DBAccess) newObject;


Compilierfehler keine, gar keine fehler eigentlich =) ich kann halt nicht die funktionen der klasse DBAccess auf dem objekt meiner instanziierten klasse anwenden. 

das ist das problem =)


----------



## SlaterB (20. Feb 2009)

'kann halt nicht die funktionen [..] anwenden'
ist keine korrekte Fehlerbeschreibung,

kommt jedes Mal, wenn du das tust, ein FBI-Mann zur Tür herein und nimmt dir die Tastatur weg?
oder reagiert das Programm in IRGENDEINER WEISE?

dann beschreibe dies bitte mit Worten..

-------

hat com.log.lud.sql.IFC_test wirklich etwas mit com.org.test.obclass.DBAccess zu tun?


----------



## tuxedo (20. Feb 2009)

Das von dir instanziierte Objekt sollte von DBAccess geerbt haben, oder falls DBAccess ein Interface ist, sollte das Objekt dieses Interface implementiert haben. Nur dann kannst du erfolgreich nach DBAccess casten und die Methoden die DBAccess beschreibt nutzen.

- Alex


----------



## vodn7v (20. Feb 2009)

ok sorry, 
also in der klasse DBAccess habe ich verschiedene Methoden, wie z.B. insert(), oder executeQuery(). die möchte ich gerne nutzen. und auf das objekt der klasse anwenden.

ich bekomme dieser aber gar nicht erst zur verfügung gestellt. würde gerne sowas machen:

com.org.test.obclass.DBAccess newTableClass = null;
Object newObject = null;


Class c = null;
try {
c = Class.forName("com.log.lud.sql.IFC_test");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
newObject = (Object) c.newInstance();
} catch (InstantiationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

newTableClass = (com.org.test.obclass.DBAccess) newObject;



dann: newTableClass.insert(irgendein datensatz);

aber die aufrufe werden mir nicht angezeigt. das meine ich damit =)


----------



## tuxedo (20. Feb 2009)

>> aber die aufrufe werden mir nicht angezeigt. das meine ich damit =)

Scheint eher was mit deiner IDE und der "autovervollständigung" zu tun haben ?!
Weil "werden mir nicht angezeigt" interessiert den Compiler erstmal nicht. 

- Alex


----------



## SlaterB (20. Feb 2009)

und falles es nicht an der IDE liegt:
die Variable newTableClass ist vom Typ DBAccess, du siehst genau die Methoden, die DBAccess zur Verfügung stellt,
wenn insert nicht dabei ist, dann fehlt diese Methode in DBAccess?

poste diese Klasse/ Interface


----------



## vodn7v (20. Feb 2009)

ok das passt schonmal, die funktionen der DBAccess werden vererbt. das geht jetzt. hatte einen pfadfehler drin, obwohl er nicht gemeckert hat.. naja.

ein problem habe ich nocht. ich kann jetzt zwar die geerbten funktionen aus der DBAccess nutzen, jedoch nicht die der Klasse von der ich das Objekt erstellt habe.

also von der "com.log.lud.sql.IFC_test"

dort ist zb. diese methode enthalten:
-----------------
public boolean deleteByKey(int key) throws SQLException
{
boolean status= false;

  if (connect())
  {
// hier findet die SQL operation statt
  }
  return TGstatus;
}
------------------
sollte doch eigentlich gehen oder? pfad etc ist alles korrekt.

wenn ich aber "objekt.deleteByKey(zahl);"

angebe makiert er mir das als fehler, nicht vorhanden etc. automatisch angezeigt wird es auch nicht.


----------



## tfa (20. Feb 2009)

Dann musst du das Objekt nach com.log.lud.sql.IFC_test casten.


----------



## vodn7v (20. Feb 2009)

hmm.. das versteh ich jetzt nicht. ich dachte mein objekt wäre ein instanz der klasse "com.log.lud.sql.IFC_test" und hätte die eigenschaften von DBAssess geerbt. warum muss ich das objekt jetzt nochma nach "com.log.lud.sql.IFC_test"  casten ??

danke


----------



## tuxedo (20. Feb 2009)

Weil du's beim Laden allgemein gehalten hast (Object) und dann lediglich nach DBAccess gecastet hast. Somit ist es als "DBAccess" bekannt. Wenn "IFC_test" von DBAccess erbt, kannst du einfach einmal nach IFC_test casten und schon hast du Zugriff auf alles in IFC_test und hast die Methoden aus DBAccess.

Kannst ja mal in der JavaInsel zum Thema "casten" nachschlagen. Dann wird dir einiges klarer.

- Alex


----------



## tfa (20. Feb 2009)

Java ist statisch getypt. Wenn eine Variable vom Typ DBAccess ist, kannst du nur Methoden aufrufen, die in der Schnittstelle von DBAccess definiert sind. Das prüft schon der Compiler. Dabei ist völlig egal, von welcher Klasse das eigentlich Objekt in dieser Variable ist.
In dynamisch typisierten Sprachen ist das anders. Da gibt es keine Casts.


----------



## vodn7v (20. Feb 2009)

glaube mein problem ist, das ich den klassennamen nicht als pfad da habe sonder lediglich als string. das ganze sollte ja variable gehalten werden ?! oder hat das damit nichts zu tun ?

danke


----------



## vodn7v (20. Feb 2009)

klar.. casten kann ich es einfach



  ((IFC_test) newObject).executeQuery("");

dann kann ich auch auf die methoden zugreifen. problem ist einfach, das ich die Klasse vorher nicht kenne und den klassennamen als string zugewiesen kriege... und so funktioniert es ja nicht =)

(("IFC_test") newObject).executeQuery("");

oder hab ich da jetzt was falsch verstanden ??

danke euch !


----------



## SlaterB (20. Feb 2009)

dann bleibt dir einerseits nur der totale Reflection-Weg:
String cl = "IFC_test";
String method = "executeQuery";

getClass(cl).newInstance().callMethod(method); (grob)


-------

dass du die Klasse nicht kennst ist ja noch halbwegs verständlich, ansonsten könnte man sich alles sparen,
aber wenigstens die Methode sollte in einem Interface vorgegeben sein,


public interface Executer {
public void executeQuery(String query);
}

wenn dann IFC_test dieses Interface implementiert, kannst du
Executer ex = (Executer) newObject;
ex.executeQuery("");
schreiben

aber das ist ja alles wie bei DBAccess, sollte eigentlich bekannt sein...


----------



## vodn7v (20. Feb 2009)

leider implementiert die klasse kein interface .. also alles von hand. die methodenaufrufe sollten aber immer gleich sein. das würde dann schonmal gehen.

				c = Class.forName("com.log.lud.sql.IFC_test");

				newObject = (Object) c.newInstance();

				c.getMethod( "executeQuery" ).invoke( newObject );

so würde es gehen, jedoch meine frage jetzt: wie kann ich der methode parameter mitgeben ?
puh, das es so umständlich wird hätte ich nicht gedacht =)


----------



## SlaterB (20. Feb 2009)

http://www.google.de/search?hl=de&q=java+reflection+method+parameter&meta=


----------

