ClassCastException bei Verwendung eines Interfaces

Ploflo82

Mitglied
Hallo Leute,

ich habe mich zur Übung daran versucht, eine Sortierer-Klasse zu implementieren, deren Methoden (bubbleSort, mergeSort, etc) jeweils ein Array eines eigenen Interfaces 'Vergleichbar' entgegennehmen. Beim Testen ist mir dann eine ClassCastException um die Ohren geflogen, die ich nicht ganz nachvollziehen kann. Ein minimalistisches Code-Beispiel (hat nichts mehr mit dem Sortieren zu tun) findet ihr unten.
Ich befürchte, ich habe das Prinzip der Polymorphie falsch verstanden...
Code:
Exception in thread "main" java.lang.ClassCastException: [LIntRFace; cannot be cast to [LIntRFaceImplementer;
        at ClassCastExceptionTest.<init>(ClassCastExceptionTest.java:6)
        at ClassCastExceptionTest.main(ClassCastExceptionTest.java:17)

Java:
class ClassCastExceptionTest {

      public ClassCastExceptionTest() {
        IntRFaceImplementer [] array = new IntRFaceImplementer[1];
        array[0] = new IntRFaceImplementer(42);
        array = (IntRFaceImplementer []) doSomething(array);     
      }
      
      public IntRFace [] doSomething(IntRFace [] arr) {
             IntRFace [] ret = new IntRFace[1];
             ret[0] = arr[0];
             return ret;
      }


      public static void main(String [] args) {
        new ClassCastExceptionTest();
      }

}

interface IntRFace {
  public int getX(IntRFace other);
}

class IntRFaceImplementer implements IntRFace {

      private int x;
      public IntRFaceImplementer(int z) {
        x = z;
      }
      
      public int getX(IntRFace other) {
        return ((IntRFaceImplementer) other).x;
      }

}

Warum verliert das IntRFaceImplementer-Objekt im IntRFace-Array seinen Typ, wenn es in ein neues Array umgespeichert wird? Ist genau dafür nicht die Polymorphie von Java gut?
Hoffe, es kann mir jemand helfen :)
LG,
Ploflo82
 
Zuletzt bearbeitet:

Schandro

Top Contributor
Das Array ist vom Typ IntRFace. Deswegen kannst du es nicht zu einem IntRFaceImplementer-Array casten. Es ist nunmal nicht vom Typ IntRFaceImplementer[].

Das das Element im Array vom Typ IntRFaceImplementer ist ist völlig egal, darum geht es nicht.

Auf der anderen Seite aber kannst du das Element im Array ohne Probleme nach IntRFaceImplementer casten.
 
S

SlaterB

Gast
Polymorphie ist eine schöne Sache, aber da kommt der Graus, der in Java alles kaputt macht, auch die dann später eingeführten Generics:
ARRAYS, buuuuhuuuu, man graut sich vor ihnen

ein IntRFace[] kannst du nicht auf IntRFaceImplementer[] casten, das [L in der Fehlermeldung steht für die Arrays

in diesem Fall durchaus zu Recht, in ein IntRFace[] könnte theoretisch auch ein Objekt einer ganz anderen Klasse, die das Interface implementiert, gespeichert werden,

was machst du dann mit dem Array als IntRFaceImplementer[] gesehen?

gefährlicher ist es andersrum, wie beim Parameter, das genauere Array kann auf ein allgemeines gecastet werden,
Folgen siehe hier:
Java:
public class Test2
{ 
    public static void main(String[] args) {
        String[] a = new String[1];
        Object[] b = a;
        b[0] = b; // ArrayStoreException, ganz unschön und zum Glück selten
    }
}

mit Listen und Generics geht vieles leichter

folgendes könntest du noch nutzen:
Java:
IntRFace [] ret = (IntRFace[]) Array.newInstance(arr[0].getClass(),1);
erzeugt in diesem Fall wiederum ein IntRFaceImplementer[]
 

KSG9|sebastian

Top Contributor
Der Code an sich ist ja schon "kaputt"..
Code:
  public int getX(IntRFace other) {
        return ((IntRFaceImplementer) other).x;
      }
Wie kannst du dich darauf verlassen, dass "other" vom Typ IntRFaceImplementer ist?
 

Ploflo82

Mitglied
Wenn ich das ganze ohne Array mache funktioniert es aber (siehe folgenden Code):

Java:
class ClassCastExceptionTest2 {

      public ClassCastExceptionTest2() {
        IntRFaceImplementer impl = new IntRFaceImplementer(42);
        impl = (IntRFaceImplementer) doSomething(impl);
        System.out.println(impl.getXSquared());
      }

      public IntRFace doSomething(IntRFace intrf) {
             IntRFace ret = intrf;
             return ret;
      }


      public static void main(String [] args) {
        new ClassCastExceptionTest2();
      }

}

interface IntRFace {
  public int getX(IntRFace other);
}

class IntRFaceImplementer implements IntRFace {

      private int x;
      public IntRFaceImplementer(int z) {
        x = z;
      }

      public int getX(IntRFace other) {
        return ((IntRFaceImplementer) other).x;
      }
      
      public int getXSquared() {
        return x*x;
      }

}

Mir ist klar, dass in Zeile 10 nur der Verweis auf das Objekt übergeben wird und keine Kopie des Objekts angelegt wird, aber warum wird nicht dasselbe auch in meiner ersten Version mit dem Array so gemacht?
 
S

SlaterB

Gast
hast du die Antworten nicht gelesen?
hast du mein Beispiel mit der ArrayStoreException nicht nachvollzogen?

ohne Denken musst du die Situation akzeptieren wie sie ist,
wenn du Denken willst, dann steht schon alles da, eine Wiederholung bringt auch nix
(Fragen dazu sind natürlich immer möglich)
 
Zuletzt bearbeitet von einem Moderator:

Ploflo82

Mitglied
[...] ein IntRFace[] kannst du nicht auf IntRFaceImplementer[] casten, das [L in der Fehlermeldung steht für die Arrays
in diesem Fall durchaus zu Recht, in ein IntRFace[] könnte theoretisch auch ein Objekt einer ganz anderen Klasse, die das Interface implementiert, gespeichert werden,[...]

Es könnte theoretisch sein, ja. Dann würde ich die Exception auch akzeptieren (muss ich natürlich sowieso ;) ), aber in diesem Fall ist in dem Array ja tatsächlich ein IntRFaceImplementer-Objekt, weswegen ich der Ansicht bin bzw. war, dass ein Typecast funktionieren müsste.

was machst du dann mit dem Array als IntRFaceImplementer[] gesehen?

Den Satz hab ich in der Tat nicht verstanden... Was meinst du damit?
 
S

SlaterB

Gast
> Den Satz hab ich in der Tat nicht verstanden... Was meinst du damit?

das ist so allgemein gesprochen, ein 20Tonner LKW fährt auf, was machst du dann mit deiner Wattebrücke über den Fluss?

> aber in diesem Fall ist in dem Array ja tatsächlich ein IntRFaceImplementer-Objekt

da die andere Richtung, String[] als Object[] verwenden, auch Probleme macht und erlaubt ist,
kann man argumentieren, dass der Compiler das durchlassen könnte, ja,

aber ist nicht nicht der Fall

gut oder schlecht kann das jeder finden wie er/ sie will ;)
besser 1/2 Fällen verhindert als alles offen vs. Behinderung in 1/2 Fällen
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L ClassCastException (JavaMail API) Allgemeine Java-Themen 3
G ClassCastException Allgemeine Java-Themen 17
A Vererbung Klassen-Downcasting wirft ClassCastException Allgemeine Java-Themen 2
S OOP ClassCastException bei casting von eigener Klasse aus Iterator Allgemeine Java-Themen 3
F Interpreter-Fehler ClassCastException wird bei Schleifenaufruf geworfen Allgemeine Java-Themen 8
T java.lang.ClassCastException: Allgemeine Java-Themen 4
C java.lang.ClassCastException Allgemeine Java-Themen 3
T java.lang.ClassCastException Allgemeine Java-Themen 7
SuperSeppel13 ClassCastException Allgemeine Java-Themen 6
W java.lang.ClassCastException Allgemeine Java-Themen 10
H setWrappedData -> classcastexception Allgemeine Java-Themen 2
G java.lang.ClassCastException Allgemeine Java-Themen 3
G Dubiose ClassCastException in typisierter Map Allgemeine Java-Themen 4
B ClassCastException Allgemeine Java-Themen 2
V ClassCastException bei ArrayList Allgemeine Java-Themen 5
R ClassCastException Allgemeine Java-Themen 14
S Problem mit generics -> ClassCastException und ka wieso Allgemeine Java-Themen 20
B ClassCastException Allgemeine Java-Themen 17
S classCastException Allgemeine Java-Themen 4
S ClassCastException beim Casten in eine Klasse Allgemeine Java-Themen 7
Z JNA Cpp-DLL String Verwendung Allgemeine Java-Themen 2
M WSDL: Doppelte Typenames (Keine Verwendung möglich) Allgemeine Java-Themen 5
F Klassen Verwendung abstrakter Klassen Allgemeine Java-Themen 9
K Saubere Verwendung von Generic Types Allgemeine Java-Themen 7
D Verwendung von Selenium Allgemeine Java-Themen 2
M Fehler bei Verwendung von TexturePaint Allgemeine Java-Themen 16
S OOP Apache Commons Math - Verwendung von Genetics - Wie werden Daten in Chromosomen gespeichert? Allgemeine Java-Themen 4
M Verwendung der Cipher von gnu crypto (Serpent) Allgemeine Java-Themen 3
B Verwendung von Packages im Java Code Allgemeine Java-Themen 10
P Richtige Verwendung eines Timers Allgemeine Java-Themen 8
T Warnungsfreie Verwendung von Generics Allgemeine Java-Themen 11
M Problem bei der Verwendung von AES Allgemeine Java-Themen 2
J Port verwendung Allgemeine Java-Themen 13
M Verwendung von unchecked exceptions & bereits vorhandenen exceptions was priorisieren Allgemeine Java-Themen 3
X Wie 'teuer' ist die Verwendung des Stack Trace ? Allgemeine Java-Themen 8
Final_Striker Exceptionhandling: Richtige Verwendung des Try/Catch Blocks Allgemeine Java-Themen 14
W Verwendung von byte Allgemeine Java-Themen 9
L Verwendung? Allgemeine Java-Themen 2
D Fehlerhafte Thread Verwendung beim arbeiten mit Sockets Allgemeine Java-Themen 6
N allg. Frage zur Verwendung von this Allgemeine Java-Themen 3
G Verwendung von DataInputStream und URL Allgemeine Java-Themen 2
C Seltsame Konstanten (und Verwendung) Allgemeine Java-Themen 15
X Exception bei Verwendung von systray4j Allgemeine Java-Themen 5
O regulärer Ausdruck zum durchsuchen eines Strings verwenden Allgemeine Java-Themen 2
T Rotationswinkel eines Bildes bestimmen Allgemeine Java-Themen 4
C Probleme beim Erstellen eines runnable-jar files Allgemeine Java-Themen 1
J JavaScript innerhalb eines Java Projekts ausführen Allgemeine Java-Themen 2
Encera Größe eines Objektes in Byte berechnen Allgemeine Java-Themen 2
8u3631984 Prüfen ob min. ein Element eines Sets in einem anderen Set enh Allgemeine Java-Themen 4
M Array Rang eines Elements Allgemeine Java-Themen 4
OnDemand Teile eines Links entfernen Allgemeine Java-Themen 6
H Auslesen eines (LDAP-)Attributs in Active Directory Allgemeine Java-Themen 2
W JSON parsen eines ,mit JS.stringify erstellten Strings Allgemeine Java-Themen 27
H Textposition eines gedrehten Textes verschieben Allgemeine Java-Themen 8
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
E Ersetzen eines Bildes in der Kopfzeile eines Word-Docx-Dokuments mit Apache POI XWPF Allgemeine Java-Themen 0
N Fahrtrichtung eines selbstfahrenden Auto ändern Allgemeine Java-Themen 3
T Letztes Zeichen eines Strings enfernen Allgemeine Java-Themen 14
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
gotzi242 Schatzsuche mithilfe eines O(log n) Algorithmus Allgemeine Java-Themen 2
C Koordinaten LONG/LAT eines neuen Punktes in bestimmter Entfernen und Winkel berechnen Allgemeine Java-Themen 3
Tobero Meine Funktion für das beinhalten eines Punktes in einem Kreis funktioniert nicht Allgemeine Java-Themen 5
LimDul Direktes return eines Array geht nicht Allgemeine Java-Themen 20
S Mittelwert anhand eines Stream berechnen Allgemeine Java-Themen 5
kodela Breite eines erweiterten Monitors feststellen Allgemeine Java-Themen 5
R Zeilen eines 2d Arrays abwechselnd links und rechts mit Nullen auffüllen Allgemeine Java-Themen 14
Zrebna Alternative Darstellung eines Codesnippets Allgemeine Java-Themen 33
kodela Inhalt eines Arrays ändert sich mysteriös Allgemeine Java-Themen 2
bueseb84 Wget mit Wildcards - oder wie lädt man bei JFrog die letzte Version eines Artifacts herunter Allgemeine Java-Themen 3
N Erkennen eines Programs Allgemeine Java-Themen 2
N Pausieren eines Programmes Allgemeine Java-Themen 4
D Input/Output Implementierung eines CommandHandlers/Parsers für viele Eingaben Allgemeine Java-Themen 26
M Gibt es eine API die den aktuellen Wert eines Indikators beim Trading zurückgibt? Allgemeine Java-Themen 7
F Wie bekommt man alle Filenamen eines Webserver Verzeichnisses Allgemeine Java-Themen 6
A Fehler beim Öffnen eines Projekts Allgemeine Java-Themen 6
N Eigenschaften eines Buttons per Setter verändern Allgemeine Java-Themen 5
S Ausfuehrung eines Programms aufzeichnen..? Allgemeine Java-Themen 4
X Ermittlung eines doppelte Paars mit Streams Allgemeine Java-Themen 50
Stonie Prüfen von direkter Implementierung eines Interfaces Allgemeine Java-Themen 7
S Vorbereitung eines Praktikums Allgemeine Java-Themen 4
H Aufruf eines Web Service anhand übergebenen Parameter Allgemeine Java-Themen 2
M Weiterleiten von empfangenen Nachrichten eines StompSessionHandlers Allgemeine Java-Themen 1
J Programm zum Suchen eines Wortes im Dateisystem Allgemeine Java-Themen 4
H Rename eines Projekts Allgemeine Java-Themen 1
J Fenstergröße eines anderen Programmes auslesen Allgemeine Java-Themen 9
ReinerCoder auf Klassen innerhalb eines package zugreifen Allgemeine Java-Themen 22
Meeresgott Erste Schritte Sourcetree - Git | Suchen eines Commits Allgemeine Java-Themen 2
E Status eines USB Mikrofon abfragen Allgemeine Java-Themen 2
DaCrazyJavaExpert OOP Ansätze und Tipps zum Porgrammieren eines Taschenrechners Allgemeine Java-Themen 25
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
JavaNewbie2.0 Start eines Anderen Programm erkennen Allgemeine Java-Themen 6
I Verbindung eines Java-Plugins mit Webserver Allgemeine Java-Themen 3
L Auswertung eines Testes funktioniert nicht Allgemeine Java-Themen 37
G Iteratoren - Wie kann man mithilfe von Iteratoren nur jeden zweiten Wert eines TreeSets ausgeben? Allgemeine Java-Themen 4
GreenTeaYT Elemente eines 2Dim LinkedList von links nach rechts ausgeben? Allgemeine Java-Themen 0
B Spalten eines 2d-Arrays Allgemeine Java-Themen 2
M Rechenprogramm eines wissenschaftlichen Taschenrechners Allgemeine Java-Themen 4
S Eigenschaften (hier Verknüpfung) eines Files lesen Allgemeine Java-Themen 2
E Typüberprüfung eines chars Allgemeine Java-Themen 5
H Hilfe bei Erstellung eines Hilfe Fenster bei Tastendruck (F1 bei Win98) Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben