# Dynamische typisierung zur Laufzeit



## Tikonteroga (14. September 2010)

Hallo,

ich habe zurzeit ein keines Schönheitsproblem bei meinem Code.

Ich muss auf folgende Methoden eines Interface (vergleichbar mit TableModel von JAVA SWING) zugreifen.


```
Object getValue(int rowIndex, int columnIndex) throw IndexOutOfBoundsException;
```

und


```
Class<?> getColumnType(int columnIndex) throws IndexOutOfBoundsException;
```

Nun möchte ich den Rückgabetyp von getValue() an eine andere Methode zur Weiterverarbeitung übergeben. Die Methode ist überladen und erwartet einen konkreten Typ, also Double, Boolean, String, Date, ...

Gibt es eine Möglichkeit, dass die Virtuelle Maschine die Typkonvertierung für mich übernimmt ?
Ich möchte nur sehr ungern den Rückgabewert von getValue() vom Typ Object mit instanceof auf jeden möglichen Typ abprüfen bzw. den className abprüfen.

Ich dachte schon ich hätte mit der Methode cast(Object object) von Class<?> eine elegante Lösung gefunden, aber wurde dann leider enttäuscht.

Der Workaround den ich zurzeit anwende ist, dass ich immer value.toString() aufrufe und mein Objekt immer als String übergebe ...

Kennt vielleicht jemand einen Trick, wie ich die Konvertierung eleganter lösen könnte ?


----------



## Thomas Darimont (14. September 2010)

Hallo,

kannst du vielleicht mal ein kleines Aufruf beispiel angeben?

Gruß Tom


----------



## Tikonteroga (14. September 2010)

Hallo,

also ich kann ja mal versuchen mein Problem genauer zu beschreiben.

Ich habe eine Implementierung von einem Interface, dass unter andem folgende Methoden spezifiziert und quasi eine Tabelle im Speicher abbildet.

public Object getValue(int rowIndex, int columnIndex) throw IndexOutOfBoundsException;

public Class<?> getColumnClass(columnIndex) throw IndexOutOfBoundsException;

public int getColumnIndex();

public int getRowIndex();

Die Daten die sich hinter diesem Interface befinden möchte ich mit der POI API in einer Excel Datei speichern. Die POI Api definiert hier für die Klasse Cell folgende Methoden.

public void setCellValue(double value);

public void setCellValue(Date value);

public void setCellValue(boolean value);

public void setCellValue(String value);

Was mir jetzt fehlt, ist folgende Methode:

public void setCellValue(Object value);

Dann könnte ich folgendes tun.

Object value = table.getValue(0, 0);

cell.setCellValue(value);

Zurzeit muss ich aber folgendes tun:

Object value = table.getValue(0, 0);

if(value instanceof Double || value instanceof Float) {
   cell.setCellValue((Double)value);
}
else if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
   cell.setCellValue((Long)value);
}
else if (value instanceof Date) {
   cell.setCellValue((Date)value);
}
else if (value instance of Boolean) {
   cell.setCellValue((Boolean)value);
}
else {
   cell.setCellValue(value.toString());
}

Gehofft hatte ich dass ich das ein Bisschen eleganter machen kann, also mit weniger Schreibarbeit.

Ich hatte mal folgendes probiert, dass hat aber nicht funktioniert.

Object value = table.getValue(0, 0);

Class<?> type = table.getColumnType(0);

cell.setCellValue(type.cast(value));

Viele Grüße

PS: Und vielen Dank fürs Helfen Thomas. Auf was frühere Beiträge von mir betrifft.


----------



## gorefest (15. September 2010)

Hi,

du kannst die Klasse zur Weiterverarbeitung mittels Reflection danach fragen. Also etwas in der Form von 

```
(FREESTYLE)

Object y = x.getValue(...);
Method m = MyZielClass.class.getMethod("zielmethod", Class[] { y.getClass() });
m.invoke(myZielInstance, y);
```

sollte es eine Methode geben, die y.getClass() als Übergabeparameter hat, wird Reflection sie für Dich finden ;-)


----------



## Tikonteroga (17. September 2010)

gorefest hat gesagt.:


> Hi,
> 
> du kannst die Klasse zur Weiterverarbeitung mittels Reflection danach fragen. Also etwas in der Form von
> 
> ...


 
Hallo,

danke für den Vorschlag. Da fällt mir ein Problem ein. Ich habe eine Methode der ein Parameter vom Typ double übergeben wird. Dieser Methode muss auch alle Objekte vom Datentyp Double, Float, Long, Integer, Short und Byte übergeben, da es für sie keine spezielle Methode gibt. Funktioniert die Lösung von dir auch mit impliziten Casts ?


----------



## gorefest (17. September 2010)

theoretisch ja, und zwar genau dann, wenn Du einen Typen übergibst, der implizit ein double sein kann.
ansonsten kannst Du ja vorher ein Double draus machen und dann Deine Methode rufen.

Allerdings stellt sich mir dann die Frage, ob ich Dein Ausgangsposting verstanden habe.

Wenn Du eh nur eine Funktion hast, die doubles nimmt, dann mach einfach ein Double aus Deinen ÜPs.

Grüße
gore


----------



## Tikonteroga (18. September 2010)

Hallo ganz so leicht ist es nicht. Ich kann ja mein Problem kurz beschreiben. Ich muss ein Query Result aus einer Datenbank in einer Excel Datei abspeichern. Und mein Problem ist, dass die POI API, die ich zum schreiben von Excel Dateien verwende, nicht für jeden Datentyp meiner Datenbank eine passende Überladung der Methode setCellValue() anbietet.

Ich muss also nicht nur double, float, long, integer, short und byte speichern sondern z. B. auch Date und boolean.

Die POI Api stellt für double, boolean und Date eine Überladung zur Verfügung.

Also:

void setCellValue(double value);
void setCellValue(boolean value);
void setCellValue(Date value);

Aber so wie ich dich jetzt verstanden habe müsste es ja funktionieren  Man kann doch immer was dazu lernen. Dankeschön.


----------

