Warum kann Integer in Java nicht in String umgewandelt werden?

95

Ich habe eine seltsame Ausnahme gefunden:

java.lang.ClassCastException: java.lang.Integer 
 cannot be cast to java.lang.String

Wie kann es möglich sein? Jedes Objekt kann in String umgewandelt werden, nicht wahr?

Der Code lautet:

String myString = (String) myIntegerObject;

Vielen Dank.

user710818
quelle
11
"Jedes Objekt kann in String umgewandelt werden" - Dies ist falsch. Vielmehr verfügt jedes Objekt über eine toString()Methode, die es in einen String konvertiert. Wie mehrere Antworten zeigen, sollten Sie dies verwenden. (Für einige Objekte wird toString()keine sehr nützliche Zeichenfolge zurückgegeben, aber für Integerwahrscheinlich genau das, was Sie möchten.)
Ted Hopp
2
""+myIntegerObjectfunktioniert auch :)
Salman von Abbas
1
In meinem Fall wurde dieser Fehler als fehlerhaft gemeldet ... Ich habe ihn verwendet Integer.toString(IntegerObject)und er hat mir diesen Fehler gegeben, aber er ist zufrieden mit IntegerObject.toString()... Und ja, das ist wirklich eine Ganzzahl, und ich habe diesen Fehler wirklich erhalten ...
Andrew
Scratch das, String.valueOf()funktioniert eigentlich nur ...
Andrew

Antworten:

155

Warum das nicht möglich ist:

Weil String und Integer nicht in derselben Objekthierarchie liegen.

      Object
     /      \
    /        \
String     Integer

Das Casting, das Sie versuchen, funktioniert nur, wenn sie sich in derselben Hierarchie befinden, z

      Object
     /
    /
   A
  /
 /
B

In diesem Fall (A) objBoder (Object) objBoder (Object) objAwird funktionieren.

Daher, wie andere bereits erwähnt haben, um eine Ganzzahl in eine Zeichenfolge umzuwandeln:

String.valueOf(integer)oder Integer.toString(integer)für primitive,

oder

Integer.toString() für das Objekt.

Bhushan
quelle
Was ist mit (A) objA, (B) objB und (B) objA?
-Ex
@ su-ex (B) objAwird nicht funktionieren. (A) objAund (B) objBwird funktionieren.
Bhushan
Entschuldigung, Sie haben Recht, dies gibt eine ClassCastException. Die anderen beiden sind ziemlich nutzlos, werden aber natürlich funktionieren.
-Ex
45

Nein, Integerund es Stringgibt verschiedene Typen. Um eine Ganzzahl in einen String umzuwandeln, verwenden Sie: String.valueOf(integer)oder Integer.toString(integer)für das Grundelement oder Integer.toString()für das Objekt.

Petar Minchev
quelle
1
@ Ted Hopp - welcher? Wenn es ein Grundelement ist, verwenden Sie die ersten beiden, wenn es das Integer-Objekt ist, verwenden Sie das dritte.
Petar Minchev
Hoppla. Ich habe den letzten Satz Ihrer Antwort nicht gesehen. Ich lösche meinen Kommentar und stimme dieser Antwort zu.
Ted Hopp
1
Ähnliches (aber nicht doppeltes) Problem: Ein 'int' kann nicht in einen String umgewandelt werden, da ein 'int' kein Objekt ist, geschweige denn in der String-Hierarchie.
Kelly S. French
20

Für intTypen verwenden Sie:

int myInteger = 1;
String myString = Integer.toString(myInteger);

Für IntegerTypen verwenden Sie:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();
DRiFTy
quelle
Dies erzwingt einen unnötigen Unboxing-Vorgang.
Ted Hopp
@ Ted Hopp siehe meine Änderungen, um zu klären, wann jede Art von toString()Methode zu verwenden ist
DRiFTy
Ich denke, dass die letzte Zeile sein sollteString myString = myIntegerObject.toString();
Ted Hopp
6

Nein. Jedes Objekt kann zu einem gegossen werden java.lang.Object, nicht zu einem String. Wenn Sie eine Zeichenfolgendarstellung für ein beliebiges Objekt wünschen, müssen Sie die toString()Methode aufrufen . Dies ist nicht dasselbe wie das Umwandeln des Objekts in einen String.

andri
quelle
5

Objekte können mit der folgenden Methode in eine Zeichenfolge konvertierttoString() werden:

String myString = myIntegerObject.toString();

Es gibt keine solche Regel für das Casting . Damit das Casting funktioniert, muss das Objekt tatsächlich von dem Typ sein, auf den Sie das Casting durchführen.

Millimoose
quelle
5

Sie können nicht explizit etwas auf ein übertragen String, das kein ist String. Sie sollten entweder verwenden:

"" + myInt;

oder:

Integer.toString(myInt);

oder:

String.valueOf(myInt);

Ich bevorzuge die zweite Form, aber ich denke, es ist eine persönliche Wahl.

Bearbeiten OK, hier ist, warum ich die zweite Form bevorzuge. Die erste Form könnte beim Kompilieren a StringBuffer(in Java 1.4) oder a StringBuilderin 1.5 instanziieren . eine weitere Sache, um Müll gesammelt zu werden. Der Compiler optimiert dies nicht, soweit ich das beurteilen kann. Das zweite Formular hat auch ein Analogon, mit Integer.toString(myInt, radix)dem Sie angeben können, ob Sie Hex, Oktal usw. möchten. Wenn Sie in Ihrem Code konsistent sein möchten (rein ästhetisch, denke ich), kann das zweite Formular an mehreren Stellen verwendet werden.

Bearbeiten 2 Ich nahm an, Sie meinten, Ihre ganze Zahl sei eine intund keine Integer. Wenn es bereits ein ist Integer, verwenden Sie toString()es einfach und fertig.

Jonathan
quelle
OP beginnt mit einem Integer-Objekt. Es ist viel effizienter, es einfach zu tun myIntegerObject.toString().
Ted Hopp
4

Sie sollten myIntegerObject.toString () aufrufen, wenn Sie die Zeichenfolgendarstellung wünschen.

Savino Sguera
quelle
2

Casting unterscheidet sich von der Konvertierung in Java, um informelle Terminologie zu verwenden.

Das Umwandeln eines Objekts bedeutet, dass das Objekt bereits das ist, in das Sie es umwandeln, und Sie erzählen dem Compiler nur davon. Wenn ich beispielsweise eine FooReferenz habe, von der ich weiß, dass sie eine FooSubclassInstanz ist, (FooSubclass)Foosagt der Compiler: "Ändern Sie die Instanz nicht, sondern wissen Sie nur, dass es sich tatsächlich um eine Instanz handelt FooSubclass."

Auf der anderen Seite Integerist an kein a String, obwohl es (wie Sie hervorheben) Methoden gibt, um ein zu erhalten String, das ein darstellt Integer. Da keine keine Instanz Integerjemals eine sein String, kann man nicht werfen Integerzu String.

yshavit
quelle
1

Wenn Sie kein Casting benötigen, müssen Sie toString () aufrufen.

Integer i = 33;
String s = i.toString();
//or
s = String.valueOf(i);
//or
s = "" + i;

Casting. Wie funktioniert es?

Gegeben:

class A {}
class B extends A {}

(A)
  |
(B)

B b = new B(); //no cast
A a = b;  //upcast with no explicit cast
a = (A)b; //upcast with an explicit cast
b = (B)a; //downcast

A und B im selben Vererbungsbaum und wir können dies:

a = new A();
b = (B)a;  // again downcast. Compiles but fails later, at runtime: java.lang.ClassCastException

Der Compiler muss Dinge zulassen, die möglicherweise zur Laufzeit funktionieren. Wenn der Compiler jedoch zu 100% weiß, dass die Besetzung möglicherweise nicht funktionieren kann, schlägt die Kompilierung fehl.
Gegeben:

class A {}
class B1 extends A {}
class B2 extends A {}

        (A)
      / \
(B1) (B2)

B1 b1 = new B1();
B2 b2 = (B2)b1; // B1 can't ever be a B2

Fehler: Nicht konvertierbare Typen B1 und B2. Der Compiler weiß zu 100%, dass die Besetzung unmöglich funktionieren könnte. Aber du kannst den Compiler betrügen:

B2 b2 = (B2)(A)b1;

aber trotzdem zur Laufzeit:

Ausnahme im Thread "main" java.lang.ClassCastException: B1 kann nicht in B2 umgewandelt werden

in deinem Fall:

          (Objekt)
            / \
(Ganzzahl) (Zeichenfolge)

Integer i = 33;
//String s = (String)i; - compiler error
String s = (String)(Object)i;

zur Laufzeit: Ausnahme im Thread "main" java.lang.ClassCastException: java.lang.Integer kann nicht in java.lang.String umgewandelt werden

Dmitry Sokolyuk
quelle
0

Verwenden Sie String.valueOf (Ganzzahl) .

Es gibt eine Zeichenfolgendarstellung der Ganzzahl zurück.

RanRag
quelle
Wie Petar oben sagt, sollte das seinString.valueOf(integer)
Urs Reupke
@UrsReupke: Danke, als ich versuchte, den Link hinzuzufügen, habe ich ihn falsch geschrieben.
RanRag
0

Verwenden Sie stattdessen .toString wie folgt:

String myString = myIntegerObject.toString();
A.Aleem11
quelle