¿Por qué la comparación de valor de cadena de operador == no llegó a Java?

50

Todo programador Java competente sabe que necesita usar String.equals () para comparar una cadena, en lugar de == porque == verifica la igualdad de referencia.

Cuando estoy tratando con cadenas, la mayoría de las veces estoy verificando la igualdad de valores en lugar de la igualdad de referencia. Me parece que sería más intuitivo si el lenguaje permitiera comparar los valores de cadena simplemente usando ==.

Como comparación, el operador de C # 's == verifica la igualdad de valores para la cadena s. Y si realmente necesita verificar la igualdad de referencia, puede usar String.ReferenceEquals.

Otro punto importante es que las cadenas son inmutables, por lo que no hay que hacer daño al permitir esta función.

¿Hay alguna razón particular por la que esto no se implementa en Java?

l46kok
fuente
12
Es posible que desee ver Scala, donde ==es la igualdad de objetos y la eqigualdad de referencia ( ofps.oreilly.com/titles/9780596155957/… ).
Giorgio el
Solo como una nota, y esto puede no ayudarlo, pero hasta donde recuerdo, puede comparar literales de cadena con un '=='
Kgrover
10
@Kgrover: puede, pero eso es solo un subproducto conveniente de la igualdad de referencia y cómo Java optimiza agresivamente los literales de coincidencia de cadenas en referencias al mismo objeto. En otras palabras, funciona, pero por razones equivocadas.
tdammers
1
@aviv el ==operador solo se asigna a Equalssi el ==operador se implementó de esa manera. El comportamiento predeterminado para ==es el mismo que ReferenceEquals(en realidad, ReferenceEqualsse define como la versión del objeto de ==)
Patrick Huizinga
3
Es una consecuencia de las decisiones de diseño que tienen mucho sentido en muchos otros escenarios. Pero como parece saberlo y preguntar esto de todos modos, me siento obligado a contrarrestar su pregunta: ¿Por qué tiene que haber un caso de uso para la comparación de referencias de cadenas?
Jacob Raihle

Respuestas:

90

Supongo que es solo consistencia, o "principio de mínimo asombro". La cadena es un objeto, por lo que sería sorprendente si se tratara de manera diferente a otros objetos.

En el momento en que salió Java (~ 1995), el simple hecho de tener algo así Stringera un lujo total para la mayoría de los programadores que estaban acostumbrados a representar las cadenas como matrices terminadas en nulo. StringEl comportamiento de ahora es lo que era en ese entonces, y eso es bueno; Cambiar sutilmente el comportamiento más adelante podría tener efectos sorprendentes y no deseados en los programas de trabajo.

Como nota al margen, podría usar String.intern()para obtener una representación canónica (interna) de la cadena, después de lo cual se podrían hacer comparaciones ==. La pasantía lleva algo de tiempo, pero después de eso, las comparaciones serán realmente rápidas.

Además: a diferencia de lo que sugieren algunas respuestas, no se trata de soportar la sobrecarga del operador . El +operador (concatenación) funciona en Strings aunque Java no admite la sobrecarga del operador; simplemente se maneja como un caso especial en el compilador, resolviendo StringBuilder.append(). Del mismo modo, ==podría haber sido manejado como un caso especial.

Entonces, ¿por qué asombrar con un caso especial +pero no con ==? Porque, +simplemente no se compila cuando se aplica a Stringobjetos que no son , por lo que eso se hace evidente rápidamente. El comportamiento diferente de ==sería mucho menos evidente y, por lo tanto, mucho más sorprendente cuando te golpea.

Joonas Pulakka
fuente
8
Los casos especiales añaden asombro.
Blrfl
17
Las cuerdas eran un lujo en 1995? ¿¿De Verdad?? Mira la historia de los lenguajes informáticos. El número de idiomas que tenían algún tipo de cadena en ese momento superaría con creces los que no. ¿Cuántos lenguajes además de C y sus descendientes usaron matrices terminadas en nulo?
WarrenT
14
@WarrenT: Claro, algunos (si no la mayoría) de los idiomas tenían algún tipo de cadena, pero creo que las cadenas recolectadas de basura con capacidad Unicode eran una novedad en 1995, creo. Por ejemplo, Python introdujo cadenas Unicode con la versión 2.0, año 2000. La elección de la inmutabilidad también era una opción controvertida en ese momento.
Joonas Pulakka
3
@JoonasPulakka Entonces quizás deberías editar tu respuesta para decir eso. Porque, tal como está, la parte del "lujo total" de su respuesta es bastante errónea.
svick
1
La internación tiene un costo: obtienes una cadena que nunca será desasignada. (Bueno, no a menos que use su propio motor de internamiento que pueda tirar).
Donal Fellows
32

James Gosling , el creador de Java, lo explicó de esta manera en julio de 2000 :

Dejé la sobrecarga del operador como una opción bastante personal porque había visto a demasiadas personas abusar de ella en C ++. He pasado mucho tiempo en los últimos cinco o seis años encuestando a las personas sobre la sobrecarga del operador y es realmente fascinante, porque la comunidad se divide en tres partes: probablemente del 20 al 30 por ciento de la población piensa que la sobrecarga del operador es engendro del diablo; alguien ha hecho algo con la sobrecarga del operador que realmente los ha marcado, porque han usado like + para la inserción de listas y hace que la vida sea realmente confusa. Gran parte de ese problema se debe al hecho de que solo hay alrededor de media docena de operadores que puede sobrecargar de manera sensata y, sin embargo, hay miles o millones de operadores que a la gente le gustaría definir, por lo que debe elegir,

Ross Patterson
fuente
50
Ah, sí, la vieja excusa de "vamos a cortar la herramienta puntiaguda para que los robles no se lastimen".
Blrfl
22
@Blrfl: Si una herramienta crea más problemas de los que resuelve, no es una buena herramienta. Por supuesto, decidir si este es el caso con la sobrecarga del operador podría convertirse en una discusión muy larga.
Giorgio el
15
-1. Esto no responde a la pregunta en absoluto. Java hace que la sobrecarga de operadores. El ==operador está sobrecargado para objetos y primitivas. El +operador está sobrecargado para byte, short, int, long, float, double, Stringy probablemente un par de los demás me olvidó. Hubiera sido perfectamente posible sobrecarga ==para Stringasí.
Jörg W Mittag
10
@Jorg: no, no lo hace. La sobrecarga del operador es imposible de definir a nivel de usuario. De hecho, hay algunos casos especiales en el compilador, pero eso apenas califica
AZ01
99
@Blrfl: No me importa que los imbéciles se lastimen. Es cuando me asoman por accidente que me molesta.
Jonas
9

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 tipos numéricos, ==compara igualdad numérica
  • Entre tipos booleanos, ==compara la igualdad booleana
  • Entre objetos, ==compara identidad de referencia
    • Use .equals(Object o)para comparar valores

Eso es. Regla simple y simple de identificar lo que quieres. Todo esto está cubierto en la sección 15.21 de la JLS . Comprende tres subsecciones que son fáciles de entender, implementar y razonar.

Una vez que permite la sobrecarga== , el comportamiento exacto no es algo en lo que pueda mirar al JLS y poner su 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 ve, tiene que regresar y verificar para ver qué significa realmente.

Dado que Java no permite la sobrecarga de operadores, se necesita una forma de tener una prueba de igualdad de valores que pueda anular la definición base. Por lo tanto, fue obligatorio por estas opciones de diseño. ==en Java prueba numérico para tipos numéricos, igualdad booleana para tipos booleanos e igualdad de referencia para todo lo demás (que puede anularse .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 más bien "esta es una decisión de diseño para facilitar estas otras cosas, es una consecuencia de ello".

Cadena interna , es un ejemplo de esto. De acuerdo con JLS 3.10.5 , todos los literales de cadena están internados. Se internan otras cadenas si se invoca .intern()en ellas. Eso "foo" == "foo"es 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, el internamiento de cadenas es algo que está en el nivel JVM que tiene un poco de exposición al usuario, pero en la abrumadora gran mayoría de los casos, no debería ser algo que le preocupe al programador (y los casos de uso para programadores no fueron algo que ocupaba un lugar destacado en la lista para los diseñadores al considerar esta función).

La gente lo señalará +y +=se sobrecargará por String. Sin embargo, eso no es ni aquí ni allá. Sigue siendo el caso de que si ==tiene un valor de igualdad de significado para String (y solo String), uno 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 Object y esperan ==comportarse de una manera y .equals()comportarse de otra manera, lo que requiere que los usuarios hagan un caso especial de todos esos métodos para String.

El contrato consistente para los ==Objetos es que solo es igualdad de referencia y que .equals(Object o)existe para todos los objetos que deben probar la igualdad de valor. Para complicar esto, se complican demasiadas cosas.


fuente
Gracias por tomarse el tiempo de responder. Esta sería una gran respuesta para las otras preguntas a las que me vinculé. Lamentablemente, esto no es adecuado para esta pregunta. Actualizaré el OP con aclaraciones basadas en los comentarios. Estoy buscando más los casos de uso en los que un usuario del idioma desearía tener falsos negativos al comparar cadenas. El lenguaje proporciona esta característica como coherencia, ahora me gustaría que vayamos un paso más allá. Tal vez pensando en esto por el diseñador del nuevo lenguaje, ¿es necesario? (desafortunadamente, no lang-design.SE)
Anonsage
3
@Anonsage no es un falso negativo. No son el mismo objeto. Eso es todo lo que está diciendo. También debo señalar que en Java 8, new String("foo") == new String("foo")puede ser cierto (ver Desduplicación de cadenas ).
1
En cuanto al diseño del lenguaje, CS.SE anuncia que puede estar en el tema allí.
ooh gracias Publicaré mis futuras preguntas de diseño de lang allí. :) Y, sí, desafortunadamente 'falso negativo' no es la forma más precisa de describir mi pregunta y lo que estoy buscando. Necesito escribir más palabras para que la gente no tenga que adivinar lo que soy. intento decir.
Anonsage
2
La "coherencia dentro del idioma" también ayuda con los genéricos
Brendan
2

Java no admite la sobrecarga del operador, lo que significa que ==solo se aplica a tipos primitivos o referencias. Cualquier otra cosa requiere la invocación de un método. Por qué los diseñadores hicieron esto es una pregunta que solo ellos pueden responder. Si tuviera que adivinar, probablemente sea porque la sobrecarga del operador trae complejidad que no estaban interesados ​​en agregar.

No soy un experto en C #, pero los diseñadores de ese lenguaje parecen haberlo configurado de manera tal que cada primitivo es un objeto structy cada uno structes un objeto. Debido a que C # permite la sobrecarga del operador, esa disposición hace que sea muy fácil para cualquier clase, no solo String, trabajar de la manera "esperada" con cualquier operador. C ++ permite lo mismo.

Blrfl
fuente
1
"Java no admite la sobrecarga del operador, lo que significa que == solo se aplica a tipos o referencias primitivas. Cualquier otra cosa requiere la invocación de un método" ==.
Giorgio el
@ Jorge: Exactamente. Vea mi comentario sobre la respuesta de Gilad Naaman.
Blrfl
Aunque eso se puede resolver mediante un método estático que compara las referencias de dos objetos (o un operador). Como en C #, por ejemplo.
Gilad Naaman el
@GiladNaaman: Eso sería un juego de suma cero porque causa el problema opuesto a lo que Java tiene ahora: la igualdad estaría en un operador y tendrías que invocar un método para comparar referencias. Además, tendría que imponer el requisito de que todas las clases implementen algo a lo que se pueda vincular ==. Eso está agregando efectivamente la sobrecarga del operador, lo que tendría enormes implicaciones en la forma en que se implementa Java.
Blrfl
1
@Blrfl: En realidad no. Siempre habrá una forma definida de comparar la referencia ( ClassName.ReferenceEquals(a,b)), y un ==operador y Equalsmétodo predeterminados que apuntan a ambos ReferenceEquals.
Gilad Naaman
2

Esto se ha hecho diferente en otros idiomas.

En Object Pascal (Delphi / Free Pascal) y C #, el operador de igualdad se define para comparar valores, no referencias, cuando se opera en cadenas.

Particularmente en Pascal, la cadena es un tipo primitivo (una de las cosas que realmente me encanta de Pascal, obtener NullreferenceException solo por una cadena no inicializada es simplemente irritante) y tener una semántica de copia en escritura, lo que hace (la mayoría de las veces) operaciones de cadena muy barato (en otras palabras, solo se nota una vez que comienza a concatenar cadenas de varios megabytes).

Entonces, es una decisión de diseño de lenguaje para Java. Cuando diseñaron el lenguaje, siguieron el camino de C ++ (como Std :: String), por lo que las cadenas son objetos, lo que en mi humilde opinión es un truco para compensar que C carezca de un tipo de cadena real, en lugar de hacer que las cadenas sean primitivas (que son).

Entonces, por una razón, solo puedo especular que hicieron que sea fácil de su parte y no codificar el operador hace una excepción en el compilador de cadenas.

Fabricio Araujo
fuente
¿Cómo responde esto a la pregunta que se hace?
mosquito el
Vea la última oración (que separé en un párrafo apropiado en una edición).
Fabricio Araujo
1
En mi humilde opinión, Stringdebería haber sido un tipo primitivo en Java. A diferencia de otros tipos, el compilador necesita saber sobre String; Además, las operaciones en él serán lo suficientemente comunes como para que muchos tipos de aplicaciones puedan presentar un cuello de botella de rendimiento (que podría ser facilitado por el soporte nativo). Un típico string[en minúsculas] tendría un objeto asignado en el montón para mantener su contenido, pero no existiría ninguna referencia "normal" a ese objeto en ninguna parte; Por lo tanto, podría ser un solo indirecto Char[]o, en Byte[]lugar de tener que ser Char[]indirectamente, a través de otro objeto.
supercat
1

En Java, no hay sobrecarga de operadores en absoluto, y es por eso que los operadores de comparación solo están sobrecargados para los tipos primitivos.

La clase 'String' no es primitiva, por lo tanto no tiene una sobrecarga para '==' y usa el valor predeterminado de comparar la dirección del objeto en la memoria de la computadora.

No estoy seguro, pero creo que en Java 7 u 8 Oracle hizo una excepción en el compilador para reconocer str1 == str2comostr1.equals(str2)

Gilad Naaman
fuente
"No estoy seguro, pero creo que en Java 7 u 8 Oracle hizo una excepción en el compilador para reconocer str1 == str2 como str1.equals (str2)": No me sorprendería: Oracle parece estar menos preocupado con minimalismo de lo que era Sun.
Giorgio el
2
Si es cierto, es un truco muy feo, ya que significa que ahora hay una clase que el lenguaje trata de manera diferente a todas las demás y rompe el código que compara las referencias. : - @
Blrfl
1
@WillihamTotland: considere el caso opuesto. Actualmente, si creo dos cadenas s1y s2les doy el mismo contenido, pasan la s1.equals(s2)comparación de igualdad ( ) pero no la misma referencia ( ==) porque son dos objetos diferentes. Cambiar la semántica de ==significa igualdad significaría s1 == s2evaluar truedónde solía evaluar false.
Blrfl
2
@Brlfl: Si bien eso es cierto, eso suena como algo excepcionalmente malo para confiar en primer lugar, ya que las cadenas son objetos inmutables e internables.
Williham Totland
2
@Giorgio: "Java 7 u 8 Oracle hizo una excepción en el compilador para reconocer str1 == str2 como str1.equals (str2)" No, la Especificación del lenguaje Java dice: Operadores de igualdad de referencia : "Si los operandos de un operador de igualdad son tanto del tipo de referencia como del tipo nulo, entonces la operación es la igualdad de objetos ". Eso es todo amigos. Tampoco encontré nada nuevo sobre esto en el borrador inicial de Java 8 .
David Tonhofer
0

Java parece haber sido diseñado para mantener una regla fundamental de que el ==operador debe ser legal cada vez que un operando se puede convertir al tipo del otro, y debe comparar el resultado de dicha conversión con el operando no convertido.

Esta regla no es exclusiva de Java, pero tiene algunos efectos de largo alcance (y desafortunadamente en mi humilde opinión) en el diseño de otros aspectos del lenguaje relacionados con el tipo. Hubiera sido más claro especificar los comportamientos ==con respecto a combinaciones particulares de tipos de operandos, y prohibir combinaciones de tipos X e Y donde x1==y1y x2==y1no implicarían x1==x2, pero los idiomas rara vez hacen eso [bajo esa filosofía, double1 == long1o tendrían que indicar si double1no es una representación exactalong1 o se niega a compilar;int1==Integer1debería estar prohibido, pero debería haber un medio conveniente y eficiente de no arrojar para probar si un objeto es un entero en caja con un valor particular (la comparación con algo que no es un entero en caja debería simplemente devolver false)].

Con respecto a la aplicación del ==operador a las cadenas, si Java hubiera prohibido las comparaciones directas entre operandos de tipo Stringy Object, podría haber evitado sorpresas en el comportamiento de ==, pero no hay un comportamiento que podría implementar para tales comparaciones que no sería sorprendente. Tener dos referencias de cadena mantenidas en tipo se Objectcomportan de manera diferente a las referencias mantenidas en tipo Stringhabría sido mucho menos sorprendente que tener cualquiera de esos comportamientos diferentes de los de una comparación legal de tipo mixto. Si String1==Object1es legal, eso implicaría que la única forma de que los comportamientos String1==String2y las Object1==Object2coincidencias String1==Object1sea ​​que coincidan entre sí.

Super gato
fuente
Debo estar perdiendo algo, pero en mi humilde opinión, ==en los objetos simplemente debería llamar a (null-safe) igual y algo más (por ejemplo, ===o System.identityEqual) debería usarse para la comparación de identidad. Inicialmente, se prohibiría mezclar primitivas y objetos (no había autoboxing antes de 1.5) y luego se podría encontrar una regla simple (por ejemplo, unbox seguro nulo, luego emitir, luego comparar).
maaartinus
@maaartinus: Un buen diseño de lenguaje debe usar operadores de igualdad separados para el valor y la igualdad de referencia. Si bien estoy de acuerdo en que, conceptualmente, habría sido posible que un int==Integeroperador devolviera falsesi el Integervalor es nulo y, de lo contrario, compare valores, ese enfoque habría sido diferente al comportamiento de ==en todas las demás circunstancias, donde incondicionalmente obliga a ambos operandos al mismo tipo antes comparándolos. Personalmente, me pregunto si se implementó el desempaquetado automático en un esfuerzo por permitir int==Integertener un comportamiento que no tenía sentido ...
supercat
... ya que el autoboxing inty hacer una comparación de referencia hubiera sido una tontería [pero no siempre fallaría]. De lo contrario, no veo ninguna razón para permitir una conversión implícita que pueda fallar con un NPE.
supercat
Creo que mi idea es consistente. Solo tenga en cuenta que en el mundo mejor, ==no tiene nada que ver identityEquals. +++ "operadores de igualdad separados para el valor y la igualdad de referencia", pero ¿cuáles? Me gustaría considerar tanto primitiva ==y equalscomo hacer valor de comparación en el sentido de que equalsse ve en el valor de la referencia. +++ Cuando se ==quiere decir equals, int==IntegerDEBE hacer autoboxing y comparar las referencias usando iguales nulos seguros. +++ Me temo que mi idea no es realmente mía, sino lo que hace Kotlin.
maaartinus
@maaartinus: Si ==nunca se probó la igualdad de referencia, entonces podría realizar una prueba de igualdad de valores segura y nula. El hecho de que se hace la igualdad de referencia de la prueba, sin embargo, limita seriamente la forma en que puede manejar las comparaciones de referencia / valor mixtos sin inconsistencia. Tenga en cuenta también que Java se fija en la noción de que los operadores promueven ambos operandos al mismo tipo, en lugar de generar comportamientos especiales basados ​​en las combinaciones de tipos involucrados. Por ejemplo, 16777217==16777216.0fregresa trueporque realiza una conversión con pérdida del primer operando a float, mientras que un ...
supercat
0

En general, hay muy buenas razones para querer probar si dos referencias de objeto apuntan al mismo objeto. He tenido muchas veces que he escrito

Address oldAddress;
Address newAddress;
... populate values ...
if (oldAddress==newAddress)
... etc ...

Puedo o no tener una función igual en tales casos. Si lo hago, la función igual puede comparar todo el contenido de ambos objetos. A menudo solo compara algún identificador. "A y B son referencias al mismo objeto" y "A y B son dos objetos diferentes con el mismo contenido" son, por supuesto, dos ideas muy diferentes.

Probablemente sea cierto que para objetos inmutables, como Strings, esto no es un problema. Con los objetos inmutables, tendemos a pensar que el objeto y el valor son lo mismo. Bueno, cuando digo "nosotros", me refiero a "yo", al menos.

Integer three=new Integer(3);
Integer triangle=new Integer(3);
if (three==triangle) ...

Por supuesto, eso devuelve falso, pero puedo ver a alguien pensando que debería ser cierto.

Pero una vez que diga que == compara los identificadores de referencia y no el contenido de los Objetos en general, hacer un caso especial para las Cadenas sería potencialmente confuso. Como alguien más dijo aquí, ¿qué pasaría si quisieras comparar los controladores de dos objetos String? ¿Habría alguna función especial para hacerlo solo para cadenas?

Y que hay con ...

Object x=new String("foo");
Object y=new String("foo");
if (x==y) ...

¿Es falso porque son dos objetos diferentes o verdadero porque son cadenas cuyo contenido es igual?

Entonces, sí, entiendo cómo los programadores se confunden con esto. Lo he hecho yo mismo, quiero decir, escribir myString == "foo" cuando quise decir si myString.equals ("foo"). Pero a menos de rediseñar el significado del operador == para todos los objetos, no veo cómo abordarlo.

Arrendajo
fuente
Tenga en cuenta que otros lenguajes modernos en la JVM, como Scala, se usan ==para significar "cadenas iguales".
Andres F.
@AndresF. (encogimiento de hombros) En Java, "<" significa "menor que", mientras que en XML "abre una etiqueta". En VB "=" puede significar "es igual a", mientras que en Java solo se usa para asignación. Etc. No es sorprendente que diferentes idiomas usen diferentes símbolos para significar lo mismo, o el mismo símbolo para significar cosas diferentes.
Jay
No fue una excavación ante tu respuesta. Fue solo un comentario. Solo estaba señalando que un lenguaje más moderno que Java aprovechó la oportunidad para rediseñar el significado de ==, tal como mencionó al final.
Andres F.
@AndresF. Y mi respuesta no fue una excavación en su comentario, solo decía que los diferentes idiomas abordan estos problemas de diferentes maneras. :-) Realmente me gusta la forma en que VB maneja esto ... pausa para los silbidos y abucheos de los que odian a VB ... "=" siempre compara el valor (para tipos definidos por el sistema), ya sea primitivo u objeto. "Es" compara las manijas de dos objetos. Eso me parece más intuitivo.
Jay
Seguro. Pero Scala está mucho más cerca de Java que Visual Basic. Me gusta pensar que los diseñadores de Scala se dieron cuenta de que el uso de Java ==era propenso a errores.
Andres F.
0

Esta es una pregunta válida para Strings, y no sólo para las cadenas, sino también para otros objetos inmutables que constituyen aproximadamente el "valor", por ejemplo Double, BigIntegere incluso InetAddress.

Para hacer que el ==operador sea utilizable con cadenas y otras clases de valor, veo tres alternativas:

  • Haga que el compilador conozca todas estas clases de valores y la forma de comparar sus contenidos. Si solo fuera un puñado de clases del java.langpaquete, lo consideraría, pero eso no cubre casos como InetAddress.

  • Permita la sobrecarga del operador para que una clase defina su ==comportamiento de comparación.

  • Elimine los constructores públicos y tenga métodos estáticos que devuelvan instancias de un grupo, siempre devolviendo la misma instancia para el mismo valor. Para evitar pérdidas de memoria, necesita algo como SoftReferences en el grupo, que no existía en Java 1.0. Y ahora, para mantener la compatibilidad, los String()constructores ya no se pueden eliminar.

Lo único que aún podría hacerse hoy sería introducir la sobrecarga del operador, y personalmente no me gustaría que Java vaya por esa ruta.

Para mí, la legibilidad del código es lo más importante, y un programador de Java sabe que los operadores tienen un significado fijo, definido en la especificación del lenguaje, mientras que los métodos están definidos por algún código, y su significado debe buscarse en el Javadoc del método. Me gustaría mantener esa distinción incluso si eso significa que las comparaciones de cadenas no podrán usar el ==operador.

Solo hay un aspecto de las comparaciones de Java que me molesta: el efecto de auto-boxing y -unboxing. Oculta la distinción entre el tipo primitivo y el envoltorio. Pero cuando los comparas ==, son MUY diferentes.

    int i=123456;
    Integer j=123456;
    Integer k=123456;
    System.out.println(i==j);  // true or false? Do you know without reading the specs?
    System.out.println(j==k);  // true or false? Do you know without reading the specs?
Ralf Kleberhoff
fuente