¿Dónde se implementa ' + ' para cadenas en el código fuente de Java? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

String es un caso especial en Java. Es una clase, que puedo examinar en el código fuente , pero también tiene su propio operador de infix +, que parece ser sugar sintáctico para StringBuilder.

Por ejemplo,

"Hello " + yourName;

Podría convertirse en

new StringBuilder().append("Hello ").append(yourName).toString();

No hay operadores definidos por el usuario en Java, así que ¿dónde se especifica + para String?

¿Podría usarse el mismo mecanismo para hacer operadores adicionales, como los vectores?

Author: sdgfsdh, 2015-09-22

5 answers

+ se implementa en java compiladores . El compilador reemplaza String + String con tiempo de compilación constantes o StringBuilder código. Tenga en cuenta que esto también se aplica a primitivas. es decir, int i=1+2 podría ser reemplazado directamente a int i=3 durante la compilación misma.

 44
Author: TheLostMind,
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-09-22 10:24:29

Usted puede comprobar con la especificación. El compilador tiene la implementación, no el código fuente Java.

Java Language Specification- 15.18.1. String Concatenation Operator +

Una implementación puede optar por realizar la conversión y concatenación en un solo paso para evitar crear y luego descartar un objeto de cadena intermedio. Para aumentar el rendimiento de la concatenación de cadenas repetidas, un compilador Java puede usar la clase StringBuffer o una técnica similar para reducir el número de objetos de cadena intermedios que se crean mediante la evaluación de una expresión.

Muestra la evidencia de que la implementación depende del compilador.

 23
Author: ꜱᴜʀᴇꜱʜ ᴀᴛᴛᴀ,
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-09-22 10:16:18

Los compiladores Java tienen la implementación de +. El Javadocs dice:

El lenguaje Java proporciona soporte especial para la cadena operador de concatenación ( + ), y para la conversión de otros objetos a cadena. La concatenación de cadenas se implementa a través de StringBuilder (o StringBuffer) y su método append. Cadena las conversiones se implementan a través del método toString, definido por Objeto y heredado por todas las clases en Java. Para adicional información sobre la concatenación y conversión de cadenas, ver Gosling, Joy, y Steele, La Especificación Del Lenguaje Java.

Puedes intentar comprobar esto:

public static void main(String[] args) {
    String s1 = "s1";
    String s2 = "s2";
    String s3 = s1 + s2;
    String s4 = new StringBuilder(s1).append(s2).toString();
}

El código anterior genera el mismo bytecode para + y cuando se usa StringBuilder:

L0
LINENUMBER 23 L0
LDC "s1"
ASTORE 1

L1
LINENUMBER 24 L1
LDC "s2"
ASTORE 2

// s3 = s1 + s2

L2
LINENUMBER 25 L2

NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

ASTORE 3

// s4 = new StringBuilder(s1).append(s2).toString()

L3
LINENUMBER 26 L3

NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

ASTORE 4
L4
LINENUMBER 27 L4
RETURN
 8
Author: Rahul Tripathi,
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-09-22 13:21:21

Mientras que actualmente la mayoría de los compiladores Java usan la cadena StringBuilder, no se especifica que debe ser siempre de esta manera. En particular, hay una propuesta para cambiar esto drásticamente en Java-9 reemplazando con una sola llamada invokedynamic e introducir una nueva metafactory que generará un MethodHandle apropiado en tiempo de ejecución para realizar la concatenación.

 5
Author: Tagir Valeev,
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-09-22 10:28:59

En cuanto al lenguaje, no, no es extensible. Este es un comportamiento específico, ninguna otra clase extiende el operador +.

En cuanto a dónde se hace esto, busque string_add (no es un verdadero JVM op) en los siguientes archivos:


En cuanto a por qué, se suponía que Java era simple, o al menos más simple que C++, y una cosa básica como la manipulación de cadenas era una especie de obligatorio. Sin embargo, la sobrecarga del operador añadiría complejidad.

 1
Author: acelent,
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-09-22 23:44:22