¿Por qué no se puede convertir Integer to String en Java?

95

Encontré una extraña excepción:

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

¿Cómo puede ser posible? Cada objeto se puede convertir en String, ¿no es así?

El codigo es:

String myString = (String) myIntegerObject;

Gracias.

usuario710818
fuente
11
"Cada objeto se puede convertir en String" - Esto es incorrecto. Más bien, cada objeto tiene un toString()método que lo convertirá en una cadena. Como señalan varias respuestas, eso es lo que debe usar. (Para algunos objetos, toString()no devuelve una cadena muy útil , pero Integerprobablemente haga exactamente lo que desea).
Ted Hopp
2
""+myIntegerObjecttambién funciona :)
Salman von Abbas
1
En mi caso, este error fue reportado por error ... Estaba usando Integer.toString(IntegerObject)y me dio este error, pero está contento con IntegerObject.toString()... Y sí, eso realmente es un Integer, y realmente recibí este error ...
Andrew
Rayar, sólo que String.valueOf()realmente funciona ...
Andrew

Respuestas:

155

Por qué esto no es posible:

Porque String y Integer no están en la misma jerarquía de Objetos.

      Object
     /      \
    /        \
String     Integer

El casting que estás probando, funciona solo si están en la misma jerarquía, p. Ej.

      Object
     /
    /
   A
  /
 /
B

En este caso, (A) objBo (Object) objB, o (Object) objAva a funcionar.

Por lo tanto, como otros ya han mencionado, para convertir un número entero en una cadena:

String.valueOf(integer), o Integer.toString(integer)para primitivo,

o

Integer.toString() para el objeto.

Bhushan
fuente
¿Qué pasa con (A) objA, (B) objB y (B) objA?
su-ex
@ su-ex (B) objAno funcionará. (A) objAy (B) objBfuncionará.
Bhushan
Lo siento, tienes razón, esto da una ClassCastException. Los otros dos son bastante inútiles pero, por supuesto, funcionarán.
su-ex
45

No, Integery Stringson de diferentes tipos. Para convertir un número entero en una cadena, use:, String.valueOf(integer)o Integer.toString(integer)para primitivo, o Integer.toString()para el objeto.

Petar Minchev
fuente
1
@Ted Hopp, ¿cuál? Si es un primitivo use los dos primeros, si es el objeto Integer use el tercero.
Petar Minchev
¡Ups! No vi esa última frase de tu respuesta. Eliminaré mi comentario y votaré a favor de esta respuesta.
Ted Hopp
1
Problema similar (pero no duplicado): un 'int' no se puede convertir en un String porque un 'int' no es un objeto, mucho menos en la jerarquía de String.
Kelly S. French
20

Para inttipos de uso:

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

Para Integertipos de uso:

Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();
DRiFTy
fuente
Esto obliga a una operación de desembalaje innecesaria.
Ted Hopp
@Ted Hopp vea mis ediciones para aclarar cuándo usar cada tipo de toString()método
DRiFTy
Creo que la última línea debería serString myString = myIntegerObject.toString();
Ted Hopp
6

No. Todos los objetos se pueden convertir en un java.lang.Object, no un String. Si desea una representación de cadena de cualquier objeto, debe invocar el toString()método; esto no es lo mismo que convertir el objeto en una cadena.

andri
fuente
5

Los objetos se pueden convertir en una cadena usando el toString()método:

String myString = myIntegerObject.toString();

No existe tal regla sobre el casting . Para que la transmisión funcione, el objeto debe ser del tipo al que se está enviando.

milimoose
fuente
5

No puedes enviar explícitamente nada a un Stringque no sea String. Debes usar:

"" + myInt;

o:

Integer.toString(myInt);

o:

String.valueOf(myInt);

Prefiero la segunda forma, pero creo que es una elección personal.

Editar OK, por eso prefiero la segunda forma. La primera forma, cuando se compila, podría instanciar a StringBuffer(en Java 1.4) o a StringBuilderen 1.5; una cosa más para ser la basura recolectada. El compilador no optimiza esto por lo que pude ver. La segunda forma también tiene un análogo, Integer.toString(myInt, radix)que te permite especificar si quieres hexadecimal, octal, etc. Si quieres ser consistente en tu código (puramente estéticamente, supongo), la segunda forma se puede usar en más lugares.

Edición 2 Supuse que querías decir que tu número entero era un inty no un Integer. Si ya es un Integer, solo utilícelo toString()y listo.

Jonathan
fuente
OP comienza con un objeto Integer. Es mucho más eficiente simplemente hacer myIntegerObject.toString().
Ted Hopp
4

Debe llamar a myIntegerObject.toString () si desea la representación de cadena.

Savino Sguera
fuente
2

La conversión es diferente a la conversión en Java, para usar terminología informal.

Transmitir un objeto significa que el objeto ya es a lo que lo está enviando, y solo se lo está diciendo al compilador. Por ejemplo, si tengo una Fooreferencia que sé que es una FooSubclassinstancia, entonces (FooSubclass)Foole dice al compilador, "no cambie la instancia, solo sepa que en realidad es un FooSubclass.

Por otro lado, an noInteger es un , aunque (como señala) existen métodos para obtener un que represente un . Dado que ninguna instancia de puede ser a , no puedes lanzar a .StringStringIntegerIntegerStringIntegerString

yshavit
fuente
1

En su caso, no necesita conversión, necesita llamar a toString ().

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

Fundición. ¿Como funciona?

Dado:

class A {}
class B extends A {}

(A)
  |
(SI)

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 y B en el mismo árbol de herencia y podemos esto:

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

El compilador debe permitir cosas que posiblemente funcionen en tiempo de ejecución. Sin embargo, si el compilador sabe al 100% que el elenco no podría funcionar, la compilación fallará.
Dado:

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

Error: Inconvertibles tipos B1 y B2. El compilador sabe al 100% que el elenco no podría funcionar. Pero puedes engañar al compilador:

B2 b2 = (B2)(A)b1;

pero de todos modos en tiempo de ejecución:

Excepción en el hilo "main" java.lang.ClassCastException: B1 no se puede convertir a B2

en tu caso:

          (Objeto)
            / \
(Entero) (Cadena)

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

en tiempo de ejecución: excepción en el hilo "principal" java.lang.ClassCastException: java.lang.Integer no se puede convertir a java.lang.String

Dmitry Sokolyuk
fuente
0

Utilice String.valueOf (integer) .

Devuelve una representación de cadena de entero.

RanRag
fuente
Como dice Petar anteriormente, eso debería serString.valueOf(integer)
Urs Reupke
@UrsReupke: gracias, de hecho, cuando estaba intentando agregar el enlace, lo reescribí mal.
RanRag
0

Use .toString en su lugar como a continuación:

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