Proceso de costura de cadenas con "+"

Recientemente estoy estudiando String. Tengo curiosidad sobre el proceso de concatenación de cadenas. Bienvenidos a discutirlo juntos. . .

Fragmento 1

 Prueba de clase pública {
     public  static  void main (String args []) { 
        String str = "hello " + "world " ; 
    } 
}

Ver estructura de archivos de clase con javap

Desde la estructura del archivo, podemos ver que "hola" + "mundo" se compila directamente en "helloworld", y esta constante se carga en la pila de operandos, y luego se almacena en la tabla de variables locales, y finalmente finaliza la devolución.

 Prueba de clase pública {
     public  static  void main (String args []) { 
        String str1 = "hello " + "world " ; 
        String str2 = "helloworld ;
     System.out.print (str.equals (str));
    } 
}

Por lo tanto, el código anterior se ejecuta igual y el resultado es verdadero: String str = "hello" + "world" y String str = "helloworld" tienen el mismo efecto.

 

Fragmento 2

 Prueba de clase pública {
     public  static  void main (String args []) { 
        String str = new String ( "helloworld " ); 
    } 
}

Ver estructura de archivos de clase con javap

Desde la estructura del archivo, podemos ver que antes que nada una nueva Cadena, copie el valor superior de la pila y empuje el valor copiado en la parte superior de la pila, luego almacénelo en la tabla de variables locales y finalmente regrese.

 

Fragmento 3

Después de comprender el proceso anterior, comenzamos a entrar en el tema.

 Prueba de clase pública {
     public  static  void main (String args []) { 
        String str = " hello " ; 
        str = str + " mundo " ; 
    } 
}

¿Qué pasa con el código anterior?

Veamos primero el archivo de clase

Primero almacene la variable str en la tabla de variables locales, luego nuevo StringBuilder (), e inicialícelo, luego llame al método StringBuilder.append () para unir las cadenas, y luego llame a nuevo String () a través de StringBuilder.toString () para obtener una nueva variable de cadena , Y luego almacene esta variable en la tabla de variables locales, y finalmente devuelva los extremos.

Entonces, el proceso del fragmento de código 3 es en realidad nuevo StringBuilder (). Append (str) .append ("world"). ToString ().

Dado que el proceso de unión de String con signo más utiliza los métodos append y toString de StringBuilder, es mejor observar el proceso de estos dos métodos.

// StringBuilder append method 
public StringBuilder append (String str) {
     // Llama a la clase padre AbstractStringBuilder append method 
    super .append (str);
     devuelve  esto ; 
}     

public AbstractStringBuilder append (String str) {
      // Si la cadena está vacía, Devuelve "null" 
     if (str == null )
         return appendNull ();
      int len = str.length ();
      // Obtenga el tamaño de la matriz, si el tamaño de la nueva cadena es mayor que la longitud de char [], entonces una nueva char [], y asigne el char original al nuevo char [] 
     allowCapacityInternal (count + len);
      //Ponga str en char [], la capa inferior llama al método local System.arraycopy 
     str.getChars (0 , len, value, count); 
     count + = len;
      return  this ; 
} 

// Obtenga el tamaño del contenedor 
private  int newCapacity ( int minCapacity) {
     // Si el tamaño de la nueva cadena + cadena existente es mayor que el tamaño de char [], el tamaño del nuevo contenedor se duplica +2 
    int newCapacity = (value.length << 1) + 2 ;
     if (newCapacity-minCapacity < 0 ) { 
          newCapacity = minCapacity; 
     } 
     //Si newCapacity <Integer.MAX_VALUE-8, entonces el tamaño de char [] se toma de newCapacity; si Integer.MAX_VALUE-8 <newCapacity <Integer.MAX_VALUE, entonces el tamaño de char [] se toma de Integer.MAX_VALUE; si newCapacity> Integer.MAX_VALUE. 
    return (newCapacity <= 0 || MAX_ARRAY_SIZE-newCapacity <0)? hugeCapacity (minCapacity): newCapacity; 
}    

 

 

// 而 StringBuilder 的 toString () 调用 的 是 new String () 
public String toString () {
      return  new String (valor, 0 , cuenta); 
}}    

 Cadena pública ( valor de char [], int offset, int count) {
     if (offset <0 ) {
         throw  new StringIndexOutOfBoundsException (offset); 
     } 
     if (recuento <= 0 ) {
         if (recuento <0 ) {
                 arrojar una  nueva StringIndexOutOfBoundsException (recuento); 
         } 
        if (desplazamiento <=value.length) {
             this .value = "" .value;
             return ; 
            } 
        } 
        if (offset> value.length- count) {
             throw  new StringIndexOutOfBoundsException (offset + count); 
        } 
        // según la longitud de la cadena después de empalmar Nuevo char [], y copie el valor de la matriz char [] original en el nuevo char [], ahorrando memoria 
        esto .value = Arrays.copyOfRange (value, offset, offset + count); 
    } 

 

Se puede ver en el código anterior: un pequeño proceso de empalme "+" utilizó System.arraycopy tres veces para copiar la matriz anterior a la nueva matriz.

)

 

Supongo que te gusta

Origin www.cnblogs.com/mjyung/p/12688295.html
Recomendado
Clasificación