Pregunta ¿Cómo convierto de int a String?


Estoy trabajando en un proyecto donde todas las conversiones de int a String se hacen así:

int i = 5;
String strI = "" + i;

No estoy familiarizado con Java. ¿Es esta práctica habitual o es algo malo, como supongo?


667
2017-11-05 11:11


origen


Respuestas:


Las formas normales serían Integer.toString(i) o String.valueOf(i).

La concatenación funcionará, pero no es convencional y podría ser un mal olor, ya que sugiere que el autor no conoce los dos métodos anteriores (¿qué más no podrían saber?).

Java tiene soporte especial para el operador + cuando se usa con cadenas (ver la documentación) que traduce el código que publicaste en:

StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(i);
String strI = sb.toString();

en tiempo de compilación. Es un poco menos eficiente (sb.append() termina llamando Integer.getChars(), Que es que Integer.toString() lo habría hecho de todos modos), pero funciona.

Para responder el comentario de Grodriguez: ** No, el compilador no lo hace optimizar la cadena vacía en este caso - mira:

simon@lucifer:~$ cat TestClass.java
public class TestClass {
  public static void main(String[] args) {
    int i = 5;
    String strI = "" + i;
  }
}
simon@lucifer:~$ javac TestClass.java && javap -c TestClass
Compiled from "TestClass.java"
public class TestClass extends java.lang.Object{
public TestClass();
  Code:
   0:    aload_0
   1:    invokespecial    #1; //Method java/lang/Object."<init>":()V
   4:    return

public static void main(java.lang.String[]);
  Code:
   0:    iconst_5
   1:    istore_1

Inicializar el StringBuilder:

   2:    new    #2; //class java/lang/StringBuilder
   5:    dup
   6:    invokespecial    #3; //Method java/lang/StringBuilder."<init>":()V

Añade la cadena vacía:

   9:    ldc    #4; //String
   11:    invokevirtual    #5; //Method java/lang/StringBuilder.append:
(Ljava/lang/String;)Ljava/lang/StringBuilder;

Agregar el entero:

   14:    iload_1
   15:    invokevirtual    #6; //Method java/lang/StringBuilder.append:
(I)Ljava/lang/StringBuilder;

Extraiga la cadena final:

   18:    invokevirtual    #7; //Method java/lang/StringBuilder.toString:
()Ljava/lang/String;
   21:    astore_2
   22:    return
}

Hay una propuesta y el trabajo en curso para cambiar este comportamiento, destinado para JDK 9.


884
2017-11-05 11:22



Es aceptable, pero nunca he escrito algo así. Yo preferiría esto:

String strI = Integer.toString(i);

236
2017-11-05 11:14



No es una buena manera.

Al hacer la conversión de int a string, esto debería usarse:

int i = 5;
String strI = String.valueOf(i);

108
2017-11-05 11:13



No es solo la optimización1. No me gusta

"" + i

porque no expresa lo que realmente quiero hacer 2.

No quiero agregar un entero a una cadena (vacía). Quiero convertir un entero en cadena:

Integer.toString(i)

O bien, no es mi preferido, pero es mejor que concatenación, obtener una representación de cadena de un objeto (entero):

String.valueOf(i)

1. Para el código que se llama con mucha frecuencia, como en los loops, la optimización es también un punto para no usar la concatenación.

2. esto no es válido para el uso de real concatenación como en  System.out.println("Index: " + i);  o  String id = "ID" + i;


56
2017-11-05 13:43



Muchos cursos introductorios de la Universidad parecen enseñar este estilo, por dos razones (en mi experiencia):

  • No requiere la comprensión de clases o métodos. Por lo general, esto se enseña mucho antes de que se mencione alguna vez la palabra "clase", ni siquiera las llamadas a métodos. Entonces usando algo como String.valueOf(…) confundiría a los estudiantes.

  • Es una ilustración de "sobrecarga del operador", de hecho, esto se nos vendió como el operador idiomático sobrecargado (pequeña maravilla aquí, ya que Java no permite la sobrecarga del operador personalizado).

Por lo tanto, puede nacer por necesidad didáctica (aunque yo argumentaría que esto es solo una mala enseñanza) o ser usado para ilustrar un principio que de otra manera es bastante difícil de demostrar en Java.


22
2017-11-05 14:08



La expresion

"" + i

lleva a conversión de cadena de i en tiempo de ejecución. El tipo general de la expresión es String. i primero se convierte a Integer objeto (new Integer(i)), entonces String.valueOf(Object obj) se llama. Entonces es equivalente a

"" + String.valueOf(new Integer(i));

Obviamente, esto es un poco menos eficiente que simplemente llamar String.valueOf(new Integer(i))que producirá el mismo resultado.

La ventaja de ""+i es que escribir es más fácil / rápido y algunas personas pueden pensar que es más fácil de leer. No es un olor a código ya que no indica ningún problema más profundo.

(Referencia: JLS 15.8.1)


16
2017-11-05 11:38



Personalmente, no veo nada malo en este código.

Es bastante útil cuando quieres registrar un valor int, y el registrador solo acepta una cadena. Diría que tal conversión es conveniente cuando necesitas llamar a un método que acepte un String, pero tienes un valor int.

En cuanto a la elección entre Integer.toString o String.valueOf, todo es una cuestión de gusto.
... E internamente, el String.valueOf llama al Integer.toString método por cierto. :)


14
2017-11-05 11:35



La otra forma de la que soy consciente es del Integer clase:

Integer.toString(int n);
Integer.toString(int n, int radix);

Un ejemplo concreto (aunque no creo que necesites ninguno):

String five = Integer.toString(5); // returns "5"

También funciona para otros tipos primitivos, por ejemplo Double.toString.

Mira aquí para más detalles.


12
2017-11-05 11:14