Serie de preguntas de la entrevista Parte 1: Cuénteme acerca de la diferencia entre == y es igual. Tu respuesta puede ser incorrecta

Recientemente, voy a repasar las preguntas de la entrevista, escribir una serie de contenido más clásico y básico en las preguntas de la entrevista y publicarlas en la cuenta pública, consolidar los conocimientos básicos y compartirlos con todos. Bienvenidos a todos para que sigan prestando atención a [Programa Nueva Visión]. El siguiente es el primero de esta serie.

La primera pregunta de la mayoría de las entrevistas no es hablar de orientación a objetos, o se trata de personajes. Este artículo hablará sobre "la diferencia entre == e iguales" desde todos los aspectos.

Diferencia conceptual

Para la comparación de cadenas (tenga en cuenta que solo cadenas), la diferencia entre == e igual tiene los siguientes dos puntos:

(1) "==" es juzgar si dos variables o instancias apuntan al mismo espacio de memoria.

(2) "es igual a" es juzgar si los valores del espacio de memoria apuntado por dos variables o instancias son los mismos.

La descripción anterior es bastante oscura desde la perspectiva de los conceptos abstractos. Para explicar claramente los conceptos anteriores, primero comprendamos brevemente el conocimiento de la asignación de memoria JVM.

Crea la asignación de memoria del objeto

En JVM, la memoria se divide en memoria de pila y memoria de pila. Normalmente, cuando creamos un objeto a través de la nueva palabra clave, llamamos al constructor del objeto para abrir espacio, almacenar los datos del objeto en la memoria del montón y generar una referencia correspondiente en la memoria de la pila al mismo tiempo.

String str = new String("程序新视界");

En el código anterior, el objeto String real se almacena en la memoria del montón, y la variable str solo contiene la dirección de referencia que apunta al objeto. Al llamar al código subsiguiente, se utilizan todas las referencias en la memoria de pila (la dirección apuntada por str).

Cómo String implementa el método equals

Después de comprender los conceptos anteriores, echemos un vistazo a cómo se implementa el método equals en String.

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

El código anterior tiene dos partes. La primera parte es comparar directamente con "==". Ya sabemos si las direcciones de referencia de los objetos de comparación son iguales. En otras palabras, si las direcciones de referencia de dos objetos son iguales, entonces son iguales.

La segunda parte del código determina si el objeto entrante es un objeto String. Si es un objeto String y cada elemento en la matriz char [] de los valores de los dos objetos String es igual, entonces son iguales.

Después de leer el código anterior, es posible que comprenda por qué necesita agregar una nota de "cadenas de solo notas" cuando sepa la diferencia entre ellas. El método equals de String compara valores porque anula el método equals.

En resumen, la comparación de String se puede mostrar en la siguiente imagen:

Cadena de entrevista

Sabemos que todas las clases en Java heredan del objeto Object, y el método equals también se define en el objeto Object:

public boolean equals(Object obj) {
    return (this == obj);
}

¿Qué vimos? ¡El método equals de Object resulta ser una dirección de referencia! Por lo tanto, si simplemente dice que "==" compara por referencia, es igual a compara por referencia al valor correspondiente, ¡lo cual es incorrecto! Esto está limitado al alcance de la clase String.

Cuando definimos una clase, si no se anula el método equals, se usa el método equals predeterminado de Object. Si reescribe este método, compárelo de acuerdo con el método reescrito. El método equals de String es uno de los ejemplos reescritos.

Definición de cadena especial

Además de definirse en forma de nuevo, String también se puede definir en forma de asignación de signo igual:

String str = "程序新视界";

Esta es una forma muy especial, los objetos se pueden generar sin new, que es esencialmente diferente de new. Esta forma de asignación se llama directa en Java, existe en el grupo constante, en lugar de almacenarse en el montón como nueva.

Al declarar una cadena de este tipo, JVM primero buscará objetos con los valores correspondientes en el grupo constante. Si es así, asígnelo a la referencia actual, es decir, la referencia original y el punto de referencia actual al mismo objeto. De lo contrario, se crea un nuevo objeto en el grupo constante. Para las cadenas declaradas en este formulario, siempre que los valores sean iguales, cualquier referencia múltiple apunta al mismo objeto.

Crear un objeto String en contraste con el nuevo formulario es lo mismo que crear otros objetos: cada llamada genera un nuevo objeto.

Verificación de ejemplo

Los siguientes ejemplos concretos se utilizan para verificar las conclusiones anteriores. Al mismo tiempo, estos ejemplos de verificación también pueden ser el contenido de las preguntas de la entrevista.

String x = "程序新视界";
String y = "程序新视界";
String z = new String("程序新视界");

System.out.println(x == y); // true
System.out.println(x == z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

La primera línea, debido a que el objeto se crea por asignación, cuando el objeto correspondiente ax ya existe en la memoria, la referencia apunta directamente al objeto original al asignar el objeto y. Por lo tanto igual.

En la segunda línea, debido a que z se crea en forma de nuevo, se creará un nuevo objeto, aquí se comparan las direcciones de referencia de los dos objetos, por lo que no son iguales.

Las líneas tercera y cuarta comparan el valor real de la cadena y, por lo tanto, son iguales.

Veamos la comparación de objetos sin anular el método de iguales. La definición de clase de entidad correspondiente y el método de prueba unitaria son los siguientes:

@Test
public void testObject(){
	Person p1 = new Person("Tom");
	Person p2 = new Person("Tom");

	System.out.println(p1.equals(p2));
}

class Person{

	public Person(String name){
		this.name = name;
	}
	
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Ejecute el método anterior, el resultado de la impresión es falso.

A través de los dos ejemplos anteriores, hemos verificado la teoría de la que hablamos anteriormente.

resumen

Después del análisis anterior, comprendo la lógica subyacente y creo que todos podrán responder con precisión cuando se encuentren con preguntas similares en una entrevista.

En pocas palabras, lo que se compara con iguales es una referencia y lo que se compara con iguales es un valor. Estrictamente hablando, está mal. Solo resolviendo los principios de implementación subyacentes, como la forma de almacenamiento del objeto JVM y reescribiendo el método de iguales, puede reflejar su fortaleza, en lugar de la memorización de memoria.

En el próximo artículo, hablemos sobre la creación de varios objetos y la lógica subyacente en la forma de un nuevo String, bienvenido a seguir prestando atención.

Enlace original: " Serie de preguntas de la entrevista Parte 1: ¿Cuénteme sobre la diferencia entre == y es igual? Tu respuesta puede ser incorrecta "


Nueva visión del procedimiento

La cuenta pública " Nueva Visión del Programa ", una plataforma que le permite mejorar simultáneamente su poder blando y su tecnología dura, proporcionando cantidades masivas de datos.

Cuenta oficial de WeChat: nueva visión del programa

Supongo que te gusta

Origin blog.csdn.net/wo541075754/article/details/108198289
Recomendado
Clasificación