[Java] 5 preguntas complicadas de la entrevista String

Inserte la descripción de la imagen aquí

1. Información general

Reimpreso: http://www.javastack.cn/article/2020/five-hard-string-questions/

Este artículo analizará cinco preguntas de la entrevista sobre la clase Java String. En estas cinco preguntas, personalmente he experimentado varias preguntas durante el proceso de la entrevista. Este artículo lo llevará a comprender por qué las respuestas a estas preguntas son así.

1. Determine si st1 y st2 definidos como tipo String son iguales y por qué

package string;

public class Demo2_String {
    
    

  public static void main(String[] args) {
    
    
    String st1 = "abc";
    String st2 = "abc";
    System.out.println(st1 == st2);
    System.out.println(st1.equals(st2));
  }

}

Resultado de salida:

La primera línea: verdadera

Segunda línea: verdadero

análisis:

Mire la primera declaración impresa 在Java中==这个符号是比较运算符,它可以基本数据类型和引用数据类型是否相等,如果是基本数据类型,==比较的是值是否相等,如果是引用数据类型,==比较的是两个对象的内存地址是否相等.

La cadena no pertenece a los tipos de datos básicos en 8, y el objeto de cadena pertenece al tipo de datos de referencia. En lo anterior, "abc" se asigna a los dos objetos de cadena st1 y st2 al mismo tiempo, y todos apuntan a la misma dirección, por lo que se imprime el primero La salida de comparación == en la declaración es verdadera

Luego miramos la comparación de equals en la segunda declaración de impresión. Sabemos que equals es un método de la clase principal de Object, y el método equals se reemplaza en la clase String.

Busque el método equals en la clase String en el documento JDK API 1.6, haga clic para ver la oración "Compare esta cadena con el objeto especificado. Si y solo si el parámetro no es nulo, y es el mismo que el objeto El resultado es verdadero cuando el objeto de cadena de la secuencia de caracteres es el mismo. ”Preste atención a esta misma secuencia de caracteres La comparación de dos matrices, listas y diccionarios introducidos más adelante es la lógica para escribir código para lograrlo.

Dado que los valores de st1 y st2 son "abc", ambos apuntan al mismo objeto y la secuencia de caracteres actual es la misma, por lo que el resultado de impresión de la segunda línea también es verdadero.

Dibujemos un gráfico de memoria para representar el código anterior, que parece más convincente.

Inserte la descripción de la imagen aquí

El proceso de memoria es aproximadamente el siguiente:

1) Ejecute primero para compilar, luego el archivo Demo2_String.class de la clase actual se carga en el área de métodos de la memoria

2) El segundo paso, el método principal se inserta en la memoria de la pila.

3) El grupo constante crea un objeto "abc" y genera una dirección de memoria

4) Luego asigne la dirección de memoria "abc" a la variable miembro st1 en el método principal. En este momento, st1 apunta a "abc" en el grupo de constantes según la dirección de memoria.

5) Como se mencionó en el artículo anterior, el grupo de constantes tiene esta característica. Si se encuentra que ya existe, no creará un objeto duplicado

6) Ejecute el código Stringst2 = "abc", porque el grupo de constantes tiene "abc", no se volverá a crear y la dirección de memoria de "abc" se asigna directamente a st2

7) Finalmente, tanto st1 como st2 apuntan a la misma dirección en la memoria, por lo que los dos son exactamente iguales.

2. La siguiente oración crea varios objetos en la memoria.

String st1 = new String(“abc”);

La respuesta es: cree dos objetos en la memoria, uno en la memoria del montón y otro en el grupo constante. El objeto de la memoria del montón es una copia del objeto del grupo constante. Además, preste atención a la cuenta pública de WeChat: pila de tecnología Java y responda en segundo plano: Entrevista, puedo obtener las últimas N preguntas de la entrevista de Java compiladas por mí, todas las cuales son productos secos.

análisis:

Vayamos directamente a un mapa de memoria a continuación.
Inserte la descripción de la imagen aquí

Cuando vemos la palabra clave new, debemos pensar que los nuevos objetos están almacenados en la memoria del montón. Luego explicamos por qué los objetos del montón son copias de los objetos del grupo constante.

"Abc" es una cadena, y una cadena es una constante, por lo que debe crearse en el grupo de constantes, por lo que el primer objeto creado es "abc" en el grupo de constantes.

¿Por qué el segundo objeto es una copia de una copia en la memoria del montón? Necesita encontrar la anotación del método de construcción String (String original) en JDK API 1.6: Inicializar un objeto String recién creado para que sea igual al parámetro La secuencia de caracteres; en otras palabras, la cadena recién creada es una copia de la cadena de parámetros.

Entonces, sale la respuesta, dos objetos.

3. Determine si st1 y st2 definidos como tipo String a continuación son iguales

package string;
public class Demo2_String {
    
    
   public static void main(String[] args) {
    
    
     String st1 = new String("abc");
     String st2 = "abc";
     System.out.println(st1 == st2);
     System.out.println(st1.equals(st2));
   }
}

Respuesta: falso y verdadero

Debido a la experiencia y la teoría del análisis de la memoria mencionadas en los dos cursos anteriores, puedo obtener rápidamente la respuesta anterior.

==比较的st1和st2对象的内存地址,由于st1指向的是堆内存的地址,st2看到“abc”已经在常量池存在,就不会再新建,所以st2指向了常量池的内存地址,所以==判断结果输出false,Los dos no son iguales.

La segunda es igual a la comparación, la comparación es si las dos secuencias de cadenas son iguales, porque solo hay un "abc", son completamente iguales.

El diagrama de memoria es el siguiente

Inserte la descripción de la imagen aquí

4. Determine si st1 y st2 definidos como tipo String a continuación son iguales

package string;

public class Demo2_String {
    
    

   public static void main(String[] args) {
    
    
     String st1 = "a" + "b" + "c";
     String st2 = "abc";
     System.out.println(st1 == st2);
     System.out.println(st1.equals(st2));
   }
}

La respuesta es: verdadera y verdadera.

análisis:

Las tres "a", "b" y "c" son originalmente constantes de cadena. Después de empalmar el signo +, se convierten en "abc". "Abc" en sí mismo es una constante de cadena (hay un mecanismo de optimización constante en Java), por lo que la constante Chi Lima creará un objeto constante de cadena de "abc", en el proceso de st2 = "abc", en este momento, "abc" existe en el grupo de constantes, por lo que no se creará. Por lo tanto, independientemente de si se compara la dirección de memoria o se compara la secuencia de cadenas, es igual.

5. Determina si los siguientes st2 y st3 son iguales

package string;

public class Demo2_String {
    
    

   public static void main(String[] args) {
    
    
     String st1 = "ab";
     String st2 = "abc";
     String st3 = st1 + "c";
     System.out.println(st2 == st3);
     System.out.println(st2.equals(st3));
   }
}

Respuesta: falso y verdadero

análisis:

La primera respuesta anterior es falsa, la segunda es verdadera y la segunda es verdadera. Lo entendemos muy bien, porque la comparación una es "abc" y la otra es el empalmado "abc", por lo que la comparación de iguales, esta es la salida cierto, lo entendemos muy bien.

Entonces, por qué el primer juicio es falso, estamos muy confundidos. De manera similar, a continuación usamos anotaciones API y diagramas de memoria para explicar por qué esto no es igual.

Primero, abra la introducción de String en JDK API 1.6 y busque la oración en la imagen a continuación.
Inserte la descripción de la imagen aquí

El punto clave es la oración en el círculo rojo. Sabemos que cualquier dato y cadena están sujetos a la operación más (+), y el resultado final es una nueva cadena empalmada. ¿Qué hizo exactamente la operación +? Recomiendo echar un vistazo. Preste atención a la cuenta pública de WeChat: pila de tecnología Java, responda en segundo plano: java, puede obtener los últimos tutoriales de Java N que he compilado, todos los cuales son productos secos.

El comentario anterior explica que el principio de este empalme es implementar el empalme mediante la clase StringBuilder o StringBuffer y el método append dentro, luego llamar a toString () para convertir el objeto empalmado en un objeto de cadena, y finalmente asignar la dirección del objeto de cadena a una variable.

Combinando esta comprensión, dibujemos un diagrama de memoria para analizar.

Inserte la descripción de la imagen aquí

Proceso de memoria aproximado

1) El grupo de constantes crea un objeto "ab" y lo asigna a st1, por lo que st1 apunta a "ab"

2) El grupo de constantes crea un objeto "abc" y lo asigna a st2, por lo que st2 apunta a "abc"

3) Debido al método de empalme + aquí, el tercer paso es usar el método append de la clase StringBuffer para obtener "abc". En este momento, la memoria 0x0011 representa un objeto StringBuffer y tenga en cuenta que no es un objeto String.

4) Se llama al método toString de Object para reemplazar el objeto StringBuffer con un objeto String.

5) Asigne el objeto String (0x0022) a st3

Por lo tanto, el resultado del juicio == de st3 y st2 no es igual, porque las direcciones de memoria de los dos objetos son diferentes.

para resumir:

Las preguntas de la entrevista para este artículo son completamente necesarias para dominar algunas de las anotaciones y principios en la API de JDK, así como el análisis del mapa de memoria, para obtener los resultados correctos. Admito que dibujar el mapa de memoria me permite entender por qué la respuesta es así.

Después de dibujar el mapa de memoria y obtener la respuesta, de hecho lo encontrará muy interesante, y finalmente tendrá un suspiro.

Supongo que te gusta

Origin blog.csdn.net/qq_21383435/article/details/108465972
Recomendado
Clasificación