¿Es tan malo concatenar con una cadena vacía para hacer una conversión de cadena?


Digamos que tengo dos variables char, y más tarde quiero concatenar en una cadena. Así es como lo haría:

char c1, c2;
// ...

String s = "" + c1 + c2;

He visto gente que dice que el "" + "truco" es "feo", etc., y que deberías usar String.valueOf o Character.toString en su lugar. Prefiero esta construcción porque:

  • Prefiero usar la función de idioma en lugar de la llamada a la API si es posible
    • En general, ¿no es el lenguaje generalmente más estable que la API?
    • Si solo la función de idioma oculta llamada API, entonces razón aún más fuerte para preferirlo!
      • Más abstracto! ¡Esconderse es bueno!
  • Me gusta que el c1 y c2 están visualmente en el mismo nivel
    • String.valueOf(c1) + c2 sugiere que hay algo especial en c1
  • Es más corto.

¿Hay realmente un buen argumento por qué String.valueOf o Character.toString es preferible a "" +?


Curiosidades: en java.lang.AssertionError, la siguiente línea aparece 7 veces, cada una con un tipo diferente:

    this("" + detailMessage);
Author: polygenelubricants, 2010-03-24

9 answers

Sus argumentos son buenos; esta es una de las áreas más expresivas del lenguaje Java, y el lenguaje "" + parece bien arraigado, como descubrió.

Ver Concatenación de cadenas en la JLS. Una expresión como

"" + c1 + c2

Es equivalente a

new StringBuffer().append(new Character(c1).toString())
                  .append(new Character(c2).toString()).toString()

Excepto que todos los objetos intermedios no son necesarios (por lo que la eficiencia no es un motivo). La especificación dice que una implementación puede usar StringBuffer o no. Dado que esta característica está integrada en el lenguaje, veo no hay razón para usar la forma más detallada, especialmente en un lenguaje ya detallado.

 25
Author: Josh Lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-24 09:35:05

El problema con esa construcción es que generalmente no expresa la intención.

Representa la concatenación de una cadena con otro valor, pero la concatenación no suele ser el objetivo de esta línea.

En el caso específico que demostraste, la concatenación es en realidad el objetivo, por lo que este código expresa la intención.

En el uso más común de este enfoque (String s = "" + intValue;), la concatentación es meramente un efecto secundario tolerado, mientras que la conversión de intValue es el objetivo actual. Y un simple String.valueOf(intValue) expresa esa intención mucho más claramente.

 19
Author: Joachim Sauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-24 09:46:47

Prefiero usar String.valueOfpara conversiones simples, pero en su caso realmente desea concatenación.

Sin embargo, sugeriría que esta versión eliminaría toda ambigüedad potencial:

String s = c1 + "" + c2;

De esa manera no hay posibilidad, por remota que sea, de que alguien considere si c1 y c2 se sumarán juntos antes de la concatenación.

 4
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 11:52:22

En mi opinión, "" + x es muy legible, corto y preciso hasta el punto. Lo preferiría a construcciones más largas como String.valueOf. El comportamiento está bien definido y es tan comúnmente en uso que me resulta difícil llamarlo un truco en absoluto.

Lo único que me preocuparía un poco es el rendimiento, y estoy muy seguro de que no importa generalmente (a pesar de que no medí ni miré el binario). También hay una buena posibilidad de que este tipo de concat se optimice, ya que debería sea fácil de detectar (esto es solo una suposición).

 2
Author: mafu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-24 09:47:53

Creo que en "" + var el + está realmente sobrecargado para hacer la conversión:

El lenguaje Java proporciona soporte especial para el operador de concatenación de cadenas ( + ), y para la conversión de otros objetos a cadenas. La concatenación de cadenas se implementa a través de la clase StringBuilder(o StringBuffer) y su método append. Las conversiones de cadena se implementan a través del método toString, definido por Object y heredado por todas las clases en Java. Para más información sobre concatenación y conversión de cadenas

Así que no hay diferencia ni problema desde un punto de vista técnico.

Formar un punto de vista de legibilidad - es una cuestión de preferencia personal o estilo de codificación acordado dentro del equipo.

 2
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-24 09:49:29

¿Qué pasa con

new String(new char[] {a, b})

Y si lo haces mucho, podrías crear una clase "Strings" con:

public static String valueOf(char... chars) {
    return new String(chars);
}

Su línea entonces leería

String s = Strings.valueOf(a, b);

Bonito y corto.

Editado

Un mejor nombre podría ser:

String s = Chars.asString(a, b);
 2
Author: whiskeysierra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-12 23:02:26

A menos que tu aplicación necesite cada onza de rendimiento, escribe el código que sea más rápido de escribir y más fácil de leer. ""+es una sintaxis más lenta de ejecutar, pero ciertamente parece más fácil de leer cada vez que la he usado.

 1
Author: Dean J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-24 13:41:05

El estilo "" + var tiene un problema muy grande en mi opinión. Solo usa el método toString del var. Por lo tanto, si cambia el tipo de var a otra cosa, no obtendrá una excepción. Un buen ejemplo que acabo de encontrar fue que el tipo se cambió de int a Optional<Integer>. El código todavía se compila bien, pero se obtiene un resultado completamente diferente.

 1
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-31 08:24:29

La mejor manera de saberlo es compilar / descompilar tu código, usé Jad http://en.wikipedia.org/wiki/JAD_ (JAva_Decompiler) para eso, verá que su expresión se convirtió en

String s = (new StringBuilder()).anexar("").append (ci).añadir (c2).toString ();

Como se puede ver javac realmente incluido append ( "" ) llamada, pero su costo es insignificante, teniendo en cuenta que se anexa al buffer interno StringBuilder, se puede comprobar la fuente de StringBuilder

 0
Author: Evgeniy Dorofeev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-06 09:14:03