Vous posez une question avec une fausse prémisse. Puisque le ==
ne compare pas les emplacements de mémoire, il n'est pas sensible aux changements d'emplacement de mémoire. en soi . Le site ==
L'opérateur, appliqué aux références, compare les identité des objets référencés, quelle que soit la manière dont la JVM l'implémente.
Pour citer un exemple qui va à l'encontre de la compréhension habituelle, une JVM distribuée peut avoir des objets conservés dans la RAM de différents ordinateurs, y compris la possibilité de copies locales. Il ne suffit donc pas de comparer les adresses. Bien entendu, c'est à l'implémentation de la JVM de s'assurer que la sémantique, telle que définie dans la spécification du langage Java, ne change pas.
Si une implémentation particulière de la JVM met en œuvre une comparaison de références en comparant directement les emplacements mémoire des objets et possède un ramasseur d'ordures qui peut modifier les emplacements de la mémoire, bien sûr, c'est à la JVM de s'assurer que ces deux fonctionnalités ne peuvent pas interférer l'une avec l'autre de manière incompatible.
Si vous êtes curieux de savoir comment cela peut fonctionner, par exemple dans un code optimisé et compilé en JIT, la granularité n'est pas aussi fine que vous pourriez le penser. Tout code séquentiel, y compris les branches avant, peut être considéré comme s'exécutant suffisamment vite pour permettre de retarder le ramassage des ordures jusqu'à son achèvement. Ainsi, le garbage collection ne peut pas se produire à n'importe quel moment dans du code optimisé, mais doit être autorisé à certains moments, par ex.
- branches arrière (notez qu'en raison du déroulement de la boucle, chaque itération de boucle n'implique pas une branche arrière)
- allocations de mémoire
- actions de synchronisation des fils
- invocation d'une méthode qui n'a pas été inlined/analysée
- peut-être quelque chose de spécial, j'ai oublié
La JVM émet donc du code contenant certains "points sûrs" où l'on sait, quelles références sont actuellement détenues, comment les remplacer, si nécessaire et, bien sûr, le changement d'emplacement n'a aucun impact sur la correction. Entre ces points, le code peut s'exécuter sans avoir à se soucier de la possibilité de changer d'emplacement mémoire, tandis que le ramasseur de déchets attendra que le code atteigne un point sûr en cas de besoin, ce qui est garanti dans un temps fini, plutôt court.
Mais, comme nous l'avons dit, ce sont des détails de mise en œuvre. Au niveau formel, des choses comme la modification des emplacements mémoire n'existent pas, il n'est donc pas nécessaire de spécifier explicitement qu'elles ne sont pas autorisées à modifier la sémantique du code Java. Aucun détail d'implémentation n'est autorisé à le faire.