# Methode createStatement()



## Wang (16. Aug 2011)

Hallo allerseits,

mir lässt leider die Methode createStatement() keine Ruhe (stammt aus einem Beispiel im Buch "Java als erste Programmiersprache"):


```
// Verbindung zum DBMC herstellen. Es wird nun implizit
// der JDBC-Treiber com.mysql.jdbc.Driver geladen.
// Der Aufruf liefert ein Objekt vom Typ Connection zurück,
// das die Verbindung zum DBMS kapselt.
Connection con = DriverManager.getConnection (url + dbName, user, passwd);

// Der Aufruf der Methode createStatement() auf dem
// Connection-Obejkt liefert ein Objekt vom Typ
// Statement zurück. Über dieses Objekt können SQL-
// Befehle an die Datenbank gesendet werden.
Statement stmt = con.createStatement();
```

Die Methode createStatement() stammt aus dem Interface Connection und besitzt damit keinen Rumpf. Wie ist es aber möglich, dass sie dennoch ein Objekt zurückgibt? ???:L

Thanks!

Gruß
Wang


----------



## Michael... (16. Aug 2011)

Wang hat gesagt.:


> Die Methode createStatement() stammt aus dem Interface Connection und besitzt damit keinen Rumpf. Wie ist es aber möglich, dass sie dennoch ein Objekt zurückgibt? ???:L


Die Methode ist ja in dem entsprechenden Datenbanktreiber implementiert bzw. in dem Connection Objekt welches von DriverManager.getConnection(...) zurückgegeben wird.


----------



## maki (16. Aug 2011)

http://de.wikipedia.org/wiki/Polymorphie_(Programmierung)


----------



## SlaterB (16. Aug 2011)

sind dir Collections bekannt?

List x = ..;
x.get();

wie kann das 'leere' Interface List eine Methode get() haben?
analoge Frage


----------



## Wang (16. Aug 2011)

Polymorphismus und Collections sind mir bekannt. 
So etwas wie 
	
	
	
	





```
List<String> x = new ArrayList<String>();
```
 ist mir also klar.

Anscheinend wird createStatement() im Connector/J (MySQL :: Download Connector/J) implementiert.

Bisher habe ich aber noch nicht rausgefunden wo genau das geschieht...


EDIT:
Scheinbar passiert es im package com.mysql.jdbc.jdbc2.optional in der Klasse ConnectionWrapper.


----------



## Wang (16. Aug 2011)

Jetzt habe ich doch noch eine Frage, da einem das teilweise "magisch" vorkommt:
Sehe ich das richtig, dass der Klassenlader hier im entsprechenden Pfad solange sucht, bis er die implementierte Methode createStatement() in der Klasse "ConnectionWrapper" findet?

Anders kann ich es mir zumindest nicht erklären...

Thanks!


----------



## XHelp (16. Aug 2011)

Wieso soll er denn suchen, wenn du schon eine Instanz davon hast?


----------



## Wang (16. Aug 2011)

Obwohl ich weiß, wo createStatement() implementiert ist, sehe ich nicht, wie der Bezug zu dieser implementierten Methode hergestellt wird. 

Das was SlaterB angesprochen hat, ist mir aber absolut klar.


----------



## maki (16. Aug 2011)

Verstehe dein Problem ehrlich gesagt nicht, kommt mir alles wie reine Zeitverschwendung vor.

Die Methode createStatement wird von der implementierenden Klasse ConnectionImpl implementiert, steht auch ziemlich offensichtlich in den Sourcen.


----------



## XHelp (16. Aug 2011)

Dann musst du eben dir die Sourcen von DriverManager angucken... aber so ganz verstanden was du willst, habe ich dennoch nicht.


----------



## Wang (16. Aug 2011)

Sorry, dass mein Problem nicht deutlich wird (Zeitverschwendung - naja, ich weiß wie man die Klassen anwendet und ich könnte an dieser Stelle "egal" sagen, aber ich möchte dennoch möchte über die Hintergründe Bescheid wissen  ).

Wir hatten:


```
Connection con = DriverManager.getConnection (url + dbName, user, passwd);
```

Das ist mir absolut klar.

Dann:


```
Statement stmt = con.createStatement();
```

An dieser Stelle möchte ich nochmals das Beispiel von SlaterB aufgreifen:


```
List<String> x = new ArrayList<String>();
x.get();
```

Im Interface List gibt es die Methode get(), welche dann u.a. in der Klasse ArrayList implementiert wird. Da ArrayList das Interface List implementiert, klappt auch der Aufruf x.get();.

Ich sehe aber nicht, warum 
	
	
	
	





```
Statement stmt = con.createStatement();
```
 funktioniert?


----------



## maki (16. Aug 2011)

> Im Interface List gibt es die Methode get(), welche dann u.a. in der Klasse ArrayList implementiert wird. Da ArrayList das Interface List implementiert, klappt auch der Aufruf x.get();.
> 
> Ich sehe aber nicht, warum Statement stmt = con.createStatement(); funktioniert?


Habe ich doch bereits beschrieben, ConnectionImpl implementiert Connection, also genau analog....


----------



## XHelp (16. Aug 2011)

Ok, ein anderes List, beispiel, vlt wird es ja deutlicher:

```
public class ArrayDriver {
  public static List<String> getList(String url) {
    List<String> result = new ArrayList<String>();
    result.add(url);
    return result;
  }
}
...
public class Tester {
  public static void main(String[] args) {
    //Connection con = DriverManager.getConnection (url + dbName, user, passwd);
    List<String> con = ArrayDriver.getList("hm");

    //Statement stmt = con.createStatement();
    String s = con.get(0);
  }
}
```


----------



## Michael... (17. Aug 2011)

Wang hat gesagt.:


> Jetzt habe ich doch noch eine Frage, da einem das teilweise "magisch" vorkommt:
> Sehe ich das richtig, dass der Klassenlader hier im entsprechenden Pfad solange sucht, bis er die implementierte Methode createStatement() in der Klasse "ConnectionWrapper" findet?


Nein, der Anwender registriert indirekt die Treiberklasse bzw. eine Instanz des Datenbanktreibers beim DriverManager:
Vor dem Aufbau einer Datenbankverbindung muss ja die Treiberklasse geladen werden 
	
	
	
	





```
Class.forName("com.mysql.jdbc.Driver")
```
 Dabei muss der Treiber so implementiert sein, dass er sich am DriverManager registriert, d.h. der DriverManager enthält dann eine Liste potentieller Treiberklassen/instanzen (In der Regel mit nur einem Eintrag). Wird eine Connection angefordert probiert der DriverManager die ihm bekannten Treiber der Reihe nach durch und liefert im Erfolgsfall eine Datenbankverbindung zurück.


----------



## oopexpert (26. Aug 2011)

ConnectionImpl implements Connection
Connection defines "Statement createStatement()"
Daraus folgt: ConnectionImpl muss "Statement createStatement()" implementieren.
Warum du ein Objekt vom Typ Statement zurückbekommst, liegt daran, dass ConnectionImpl ein neues erzeugt...


----------

