Object cast exception

Hoppla

Mitglied
Hallo!
Ich versuche eine Datenstruktur, die mir von einer Hardware geliefert wird, in eine Java-Klasse zu konvertieren.
Im Eclipse Debugger sehe ich folgende Struktur (hier mit Namen "e"):
pic1.jpg

Ich habe nun eine Java Klasse entsprechend aufgesetzt:
Java:
    private class ErrLog {
      Integer a;
      Integer b;
      Integer c;
      Integer d;
      Integer e;
      Integer f;
      Integer g;
      Integer h;
      Integer i;
      Integer j;
      String k;
      Integer l;
      String m;
      Integer n;
      Integer o;
    }

Wenn ich die mit Werten initialisiere, dann sieht die im debugger auch genaus so aus (hier mit Namen "err"):
pic2.jpg

Beim casten
Java:
err.getClass().cast(e);
wird dann jedoch eine cast exception geworfen.
(Cannot cast [Ljava.lang.Object; to VS050$BCAPMove$ErrLog)
Kann mir jemand sagen, wieso?
 
Also, zum einen castet du nich das Objekt sondern versucht ein Class-Objekt zu casten. Das geht grundsätzlich nicht.

Syntaktisch näher dran wäre:
Java:
ErrLog errLog = (ErrLog)e;

Aber auch das wird nicht funktionieren. Ein Cast übernimmt keine Werte. Du kannst nur Objekte aufeinander casten, wenn das eine eine Ableitung des anderen ist. Nur weil die Strukturen gleich sind, kann man nicht casten.

Du musst schon die Klasse verwenden, die e wirklich hat. Mach einfach mal System.out.println(e.getClass()) - dann siehst du welche Klasse es ist.
 
e ist einfach ein Array keine Objektinstanz mit Feldern. Man kann nicht einfach ein Array zu etwas völlig anderem casten. Du kannst einen Konstruktor erstellen, welcher ein Array als Parameter verwendet und dann die Elemente des Arrays einem Feld deines Objektes zuweisen.
 
Also, zum einen castet du nich das Objekt sondern versucht ein Class-Objekt zu casten. Das geht grundsätzlich nicht.

Syntaktisch näher dran wäre:
Java:
ErrLog errLog = (ErrLog)e;

Aber auch das wird nicht funktionieren. Ein Cast übernimmt keine Werte. Du kannst nur Objekte aufeinander casten, wenn das eine eine Ableitung des anderen ist. Nur weil die Strukturen gleich sind, kann man nicht casten.

Du musst schon die Klasse verwenden, die e wirklich hat. Mach einfach mal System.out.println(e.getClass()) - dann siehst du welche Klasse es ist.
Die Ausgabe ist:
class [Ljava.lang.Object;
 
e ist einfach ein Array keine Objektinstanz mit Feldern. Man kann nicht einfach ein Array zu etwas völlig anderem casten. Du kannst einen Konstruktor erstellen, welcher ein Array als Parameter verwendet und dann die Elemente des Arrays einem Feld deines Objektes zuweisen.
Passt. Vielen, vielen Dank für deine Antwort!

Meine Klasse sieht jetzt so aus:
Java:
    private class ErrLog {
      Integer a;
      Integer b;
      Integer c;
      Integer d;
      Integer e;
      Integer f;
      Integer g;
      Integer h;
      Integer i;
      Integer j;
      String k;
      Integer l;
      String m;
      Integer n;
      Integer o;

      private ErrLog(Object[] error) {
        a = (Integer) error[0];
        b = (Integer) error[1];
        c = (Integer) error[2];
        d = (Integer) error[3];
        e = (Integer) error[4];
        f = (Integer) error[5];
        g = (Integer) error[6];
        h = (Integer) error[7];
        i = (Integer) error[8];
        j = (Integer) error[9];
        k = (String) error[10];
        l = (Integer) error[11];
        m = (String) error[12];
        n = (Integer) error[13];
        o = (Integer) error[14];
      }
    }

Und wird so aufgerufen:
Code:
ErrLog err = new ErrLog((Object[]) e);

Vielen Dank nochmals!
 
Es ist ziemlich riskant so vorzugehen, dass führt schnell mal zu einer Exception. Du hast keine Garantie, dass im Array immer der gleiche Datentyp am gleichen Index übergeben wird. Ich würde das Array so speichern wie es ankommt. Dann würde ich mit Methoden darauf zugreifen. Die Methoden prüfen ob der Typ richtig ist und geben in dem Fall den Wert zurück. Falls der Typ nicht stimmt kannst du eine Exception werfen oder einen Default weitergeben.
Der Name ErrLog deutet darauf hin, dass du die Werte loggen möchtest. Dann könnte man generell nur Strings speichern:
Java:
String a = error[0] == null ? "" : error[0].toString();
In dem Fall bleibt aber das Problem mit dem Index - es könnte zu einem ArrayIndexOutOfBounds kommen.
Java:
String a = error == null || error.length <= 0 || error[0] == null ? "" : error[0].toString();
String b = error == null || error.length <= 1 || error[1] == null ? "" : error[1].toString();
(Das ist nicht schön aber selten ...)
 
Zuletzt bearbeitet:
Eine wirkliche Garantie habe ich nicht, das stimmt. Aber immerhin ist der Rückgabewert vom Hersteller exakt so spezifiziert (ich habe die Spec. auch). Insofern bin ich guter Dinge, dass das so in Ordnung ist. Aber trotzdem Danke für den Hinweis!
 
Java:
String a = error[0] == null ? "" : error[0].toString();
In dem Fall bleibt aber das Problem mit dem Index - es könnte zu einem ArrayIndexOutOfBounds kommen.
Java:
String a = error == null || error.length <= 0 || error[0] == null ? "" : error[0].toString();
String b = error == null || error.length <= 1 || error[1] == null ? "" : error[1].toString();
(Das ist nicht schön aber selten ...)
Das Ganze ließe sich mittels ArrayUtils aus den Apache Commons sogar noch etwas entschärfen:
Java:
String a = ArrayUtils.get(error, 0, "").toString();
String b = ArrayUtils.get(error, 1, "").toString();
...
Oder in Anbetracht der zahlreichen Aufrufe gleich in eine Hilfsmethode auslagern. Da ist es dann egal was diese intern benutzt:
Java:
String a = getElementAsString(error, 0);
String b = getElementAsString(error, 1);
...
 

Zurück
Oben