Consistencia dentro del lenguaje. Tener un operador que actúe de manera diferente puede ser sorprendente para el programador. Java no permite a los usuarios sobrecargar a los operadores, por lo tanto, la igualdad de referencia es el único significado razonable para ==
entre objetos.
Dentro de Java:
- Entre los tipos numéricos,
==
compara la igualdad numérica
- Entre los tipos booleanos,
==
compara la igualdad booleana
- Entre los objetos,
==
compara la identidad de referencia
- Use
.equals(Object o)
para comparar valores
Eso es todo. Regla simple y sencilla para identificar lo que quieres. Todo esto está cubierto en sección 15.21 del JLS . Comprende tres subsecciones que son fáciles de entender, implementar y razonar.
Una vez que permita la sobrecarga de ==
, el comportamiento exacto no es algo que pueda ver en el JLS y poner el dedo en un elemento específico y decir "así es como funciona", el código puede ser difícil de razonar. El comportamiento exacto de ==
puede ser sorprendente para un usuario. Cada vez que lo veas, tienes que regresar y verificar lo que realmente significa.
Dado que Java no permite la sobrecarga de operadores, se necesita una forma de tener una prueba de igualdad de valores en la que se pueda anular la definición básica de. Por lo tanto, fue mandado por estas opciones de diseño. ==
en Java prueba los tipos numéricos, la igualdad booleana para los tipos booleanos y la igualdad de referencia para todo lo demás (que puede reemplazar a .equals(Object o)
para hacer lo que quieran para la igualdad de valores).
Este no es un problema de "hay un caso de uso para una consecuencia particular de esta decisión de diseño", sino que "esta es una decisión de diseño para facilitar estas otras cosas, esto es una consecuencia de ello".
Interning de cadena , es un ejemplo de esto. De acuerdo con JLS 3.10.5 , Todos los literales de cadena están internados. Otras cadenas se internan si se invoca .intern()
en ellas. Que "foo" == "foo"
sea cierto es una consecuencia de las decisiones de diseño tomadas para minimizar la huella de memoria ocupada por los literales de cadena. Más allá de eso, String interning es algo que está en el nivel de JVM que tiene un poco de exposición para el usuario, pero en la inmensa mayoría de los casos, no debe ser algo que concierne al programador (y los casos de uso para programadores no lo son). algo que estaba en la lista de los diseñadores al considerar esta característica).
La gente indicará que +
y +=
están sobrecargados para String. Sin embargo, eso no es ni aquí ni allá. Sigue siendo el caso que si ==
tiene un significado de igualdad de valor para String (y solo String), se necesitaría un método diferente (que solo existe en String) para la igualdad de referencia. Además, esto complicaría innecesariamente los métodos que toman a Object y esperan que ==
se comporte de una manera y .equals()
se comporte a otros usuarios que requieren el caso especial de todos los métodos esos para String.
El contrato consistente para ==
en Objetos es que solo es igualdad de referencia y que .equals(Object o)
existe para todos los objetos que debe probar para la igualdad de valor. Complicar esto complica demasiadas cosas.