posicion - manejo de cadenas en java
¿Dónde se implementa `+` para cadenas en el código fuente de Java? (5)
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 una string_add
JVM real) 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 algo básico como la manipulación de cadenas era algo obligatorio. Sin embargo, la sobrecarga del operador agregaría complejidad.
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo reemplaza la clase String al operador +? 7 respuestas
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 infijo +
, que parece ser azúcar sintáctica para StringBuilder
.
Por ejemplo,
"Hello " + yourName;
podría convertirse
new StringBuilder().append("Hello ").append(yourName).toString();
No hay operadores definidos por el usuario en Java, entonces, ¿dónde +
especifica para String
?
¿Se podría usar el mismo mecanismo para hacer operadores adicionales, como por ejemplo para vectores?
Los compiladores de Java tienen la implementación para +. Los Javadocs dicen:
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 de adición. Las conversiones de cadenas se implementan a través del método toString, definido por Object y heredado por todas las clases en Java. Para obtener información adicional sobre la concatenación y conversión de cadenas, consulte Gosling, Joy y Steele, The Java Language Specification.
Puedes intentar verificar 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
Puede verificar con las especificaciones. El compilador tiene la implementación de él, no el código fuente de Java.
Java Language Specification- 15.18.1. String Concatenation Operator +
Una implementación puede optar por realizar la conversión y la concatenación en un solo paso para evitar crear y luego descartar un objeto String intermedio. Para aumentar el rendimiento de la concatenación repetida de cadenas, un compilador Java puede usar la clase StringBuffer o una técnica similar para reducir el número de objetos String intermedios que se crean mediante la evaluación de una expresión.
Muestra la evidencia de que la implementación depende del compilador.
Si bien actualmente la mayoría de los compiladores de Java utilizan la cadena StringBuilder
, no se especifica que siempre deba ser así. En particular, hay una proposal para cambiar esto drásticamente en Java-9 que reemplaza con una única invokedynamic
e introduce una nueva metafactory que generará un MethodHandle
apropiado en tiempo de ejecución para realizar la concatenación.
+
se implementa en compiladores de Java. El compilador reemplaza String
+ String
con constantes de tiempo de compilación o código de StringBuilder
. Tenga en cuenta que esto también se aplica a los primitivos . es decir, int i=1+2
podría ser reemplazado directamente por int i=3
durante la compilación misma.