Pourquoi ne peut pas convertir Integer en String en Java?


95

J'ai trouvé une exception étrange:

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

Comment cela peut-il être possible? Chaque objet peut être converti en String, n'est-ce pas?

Le code est:

String myString = (String) myIntegerObject;

Merci.


11
"Chaque objet peut être converti en chaîne" - C'est faux. Au contraire, chaque objet a une toString()méthode qui le convertira en String. Comme plusieurs réponses le soulignent, c'est ce que vous devez utiliser. (Pour certains objets, toString()ne renvoie pas une chaîne très utile , mais pour Integer, il fait probablement exactement ce que vous voulez.)
Ted Hopp

2
""+myIntegerObjectfonctionne aussi :)
Salman von Abbas

1
Dans mon cas, cette erreur a été signalée en faute ... J'utilisais Integer.toString(IntegerObject)et cela m'a donné cette erreur, mais c'est content de IntegerObject.toString()... Et oui, c'est vraiment un Integer, et j'ai vraiment eu cette erreur ...
Andrew

Grattez ça, ça ne String.valueOf()fonctionne que réellement ...
Andrew

Réponses:


155

Pourquoi ce n'est pas possible:

Parce que String et Integer ne sont pas dans la même hiérarchie d'objets.

      Object
     /      \
    /        \
String     Integer

Le casting que vous essayez, ne fonctionne que s'ils sont dans la même hiérarchie, par exemple

      Object
     /
    /
   A
  /
 /
B

Dans ce cas, (A) objBou (Object) objBou (Object) objAfonctionnera.

Par conséquent, comme d'autres l'ont déjà mentionné, pour convertir un entier en chaîne, utilisez:

String.valueOf(integer), ou Integer.toString(integer)pour primitif,

ou

Integer.toString() pour l'objet.


Qu'en est-il de (A) objA, (B) objB et (B) objA?
su-ex

@ su-ex (B) objAne fonctionnera pas. (A) objAet (B) objBfonctionnera.
Bhushan

Désolé, vous avez raison, cela donne une ClassCastException. Les deux autres sont tout à fait inutiles mais fonctionneront bien sûr.
su-ex

45

Non, Integeret Stringsont de types différents. Pour convertir un entier en chaîne, utilisez:, String.valueOf(integer)ou Integer.toString(integer)pour primitive, ou Integer.toString()pour l'objet.


1
@Ted Hopp - lequel? S'il s'agit d'une primitive, utilisez les deux premiers, s'il s'agit de l'objet Integer, utilisez le troisième.
Petar Minchev

Oups. Je n'ai pas vu cette dernière phrase de votre réponse. Je supprime mon commentaire et je vote cette réponse.
Ted Hopp

1
Problème similaire (mais pas en double): un 'int' ne peut pas être converti en String car un 'int' n'est pas un objet, encore moins dans la hiérarchie String.
Kelly S.Français

20

Pour les inttypes, utilisez:

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

Pour les Integertypes, utilisez:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();

Cela force une opération de déballage inutile.
Ted Hopp

@Ted Hopp voir mes modifications pour clarifier quand utiliser chaque type de toString()méthode
DRiFTy

Je pense que la dernière ligne devrait êtreString myString = myIntegerObject.toString();
Ted Hopp

6

Non. Chaque objet peut être lancé en un java.lang.Object, pas en un String. Si vous voulez une représentation sous forme de chaîne de n'importe quel objet, vous devez appeler la toString()méthode; ce n'est pas la même chose que de convertir l'objet en String.


5

Les objets peuvent être convertis en chaîne à l'aide de la toString()méthode:

String myString = myIntegerObject.toString();

Il n'y a pas de règle de ce genre concernant le casting . Pour que la diffusion fonctionne, l'objet doit en fait être du type vers lequel vous effectuez la diffusion.


5

Vous ne pouvez pas lancer explicitement quoi Stringque ce soit dans un qui n'est pas un String. Vous devez utiliser soit:

"" + myInt;

ou:

Integer.toString(myInt);

ou:

String.valueOf(myInt);

Je préfère la deuxième forme, mais je pense que c'est un choix personnel.

Modifier OK, voici pourquoi je préfère la deuxième forme. La première forme, une fois compilée, pouvait instancier a StringBuffer(en Java 1.4) ou a StringBuilderen 1.5; encore une chose à ramasser. Le compilateur n'optimise pas cela pour autant que je sache. La deuxième forme a aussi un analogue, Integer.toString(myInt, radix)qui vous permet de spécifier si vous voulez hex, octal, etc. Si vous voulez être cohérent dans votre code (purement esthétique, je suppose), la deuxième forme peut être utilisée à plus d'endroits.

Edit 2 J'ai supposé que vous vouliez dire que votre entier était un intet non un Integer. Si c'est déjà un Integer, utilisez- toString()le et c'est fait.


OP démarre avec un objet Integer. C'est beaucoup plus efficace de simplement faire myIntegerObject.toString().
Ted Hopp

4

Vous devez appeler myIntegerObject.toString () si vous voulez la représentation sous forme de chaîne.


2

La diffusion est différente de la conversion en Java, pour utiliser une terminologie informelle.

Le cast d'un objet signifie que cet objet est déjà ce vers quoi vous le castez, et vous en parlez simplement au compilateur. Par exemple, si j'ai une Fooréférence que je sais être une FooSubclassinstance, alors (FooSubclass)Foodit au compilateur, "ne changez pas l'instance, sachez simplement que c'est en fait un FooSubclass.

D'un autre côté, un Integern'est pas un String, bien que (comme vous le faites remarquer) il existe des méthodes pour obtenir un Stringqui représente un Integer. Étant donné qu'aucune instance de Integerne peut jamais être un String, vous ne pouvez pas lancer Integerde cas String.


1

Dans votre cas, vous n'avez pas besoin de cast, vous devez appeler toString ().

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

Fonderie. Comment ça marche?

Donné:

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 et B dans le même arbre d'héritage et nous pouvons ceci:

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

Le compilateur doit autoriser les choses qui pourraient éventuellement fonctionner à l'exécution. Cependant, si le compilateur sait à 100% que la distribution ne pourrait pas fonctionner, la compilation échouera.
Donné:

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

Erreur: types d'inconvertibles B1 et B2. Le compilateur sait à 100% que la distribution ne pourrait pas fonctionner. Mais vous pouvez tromper le compilateur:

B2 b2 = (B2)(A)b1;

mais de toute façon à l'exécution:

Exception dans le thread "main" java.lang.ClassCastException: B1 ne peut pas être converti en B2

dans ton cas:

          (Objet)
            / \
(Entier) (Chaîne)

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

au moment de l'exécution: Exception dans le thread "main" java.lang.ClassCastException: java.lang.Integer ne peut pas être converti en java.lang.String


0

Utilisez String.valueOf (entier) .

Il renvoie une représentation sous forme de chaîne d'un entier.


Comme Petar le dit ci-dessus, cela devrait êtreString.valueOf(integer)
Urs Reupke

@UrsReupke: merci, en fait quand j'essayais d'ajouter le lien, je l'ai réécrit mal.
RanRag

0

Utilisez plutôt .toString comme ci-dessous:

String myString = myIntegerObject.toString();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.