9
votes

Quelle est la différence entre être peu profond et profondément égale? Comment cela est-il appliqué à la mise en cache?

a trouvé ce qui suit dans mes notes, mais je suis incapable de le faire sentir:

Les classes d'emballage de type primitif Mixent la mise en cache pour un nombre limité des valeurs.
Cela garantit qu'un nombre limité d'objets d'emballage profondément égaux sont également peu profond: Si o1.equals (O2) alors o1 == o2 .
Par exemple, neuf entier (0) == nouveau entier (0) .
En général, cela ne fonctionne pas toujours.
Par exemple, nouveau entier (666) == nouveau entier (666)
peut ne pas tenir.
La raison de la mise en cache est que cela sauve la mémoire.
En général Caching fonctionne pour "petites" valeurs primitives.

Je ne comprends pas ce que l'on entend par ceci, ni quelle est la différence entre une profonde (anearals ()) et peu profonde (==) est égale. Je sais en pratique, les angles doivent être utilisés pour des objets et == pour des valeurs intégrales, mais le raisonnement réel de cela me fait allusion.

Je suppose que par les noms que peu profonds vérifie peut-être que les deux valeurs sont du même type et le même nom, ce qui vérifie les deux variables pointant vers le même objet? Je ne vois pas comment la mise en cache entrerait en jeu ici, ou pourquoi cela serait utile.


1 commentaires

Eh bien, vos notes sont complètement fausses. neuf entier (0) == nouveau entier (0) sera jamais, jamais, jamais est vrai, pas plus que neuf entier ( 666) == Nouveau Entier (666) . Je vous suggère de demander à votre professeur de clarification sur ce qu'il voulait dire, car s'il s'y attend sur un examen, il sait peu de java.


5 Réponses :


7
votes

Lorsque vous faites == Vous comparez les références pour l'égalité. Cela signifie que vous dites "est l'adresse en mémoire de la même manière pour les deux objets?"

Lorsque vous faites .equals () Vous comparez les objets eux-mêmes pour l'égalité. Cela signifie que vous dites "Ces deux objets se considèrent comme égaux?"

L'exemple qui a été donné était médiocre. La seule mise en cache effectuée pour ces chiffres qui est mandatée par le JLS est le .valueof () méthode. Le constructeur n'est pas mis en cache.

En outre, le JLS Spécifie uniquement le minimum que vous devez cache [-128: 127]. Les implémentations JVM peuvent mettre en cache plus si elles le souhaitent. Cela signifie integer.valueof (500) == INTEGER.VALUEOF (500) peut être false sur certaines machines, mais vrai sur les autres. < / p> xxx

résulte: xxx

voir une réponse plus détaillée ici (les commentaires sont un gemme!): Pourquoi les gens utilisent-ils toujours des types primitifs en Java?


2 commentaires

Salut, comment sont les sorties de system.out.println (integer.valueof (5) == INTEGER.VALUEOF (5)); System.out.println (integer.valueof (500) == Integer.Valueof (500)); différent??


C'est tout le point de la réponse: 5 est suffisamment petit que la JVM en cache, tandis que 500 n'est pas. Bien que cela puisse être, donc sur certaines machines rares, cela pourrait être la même chose (à la fois vrai), mais sur la plupart des machines 5 seront cèdées et renvoient ainsi le même objet entier tandis que 500 ne sera pas si ValueOf créera neuf entier s.



1
votes

Equals () teste si deux objets sont essentiellement les mêmes, mais il peut retourner vrai pour deux objets distincts; C'est-à-dire, deux clips de papier différents sont "égaux". "==" Pour les types de référence teste si deux références se réfèrent au même objet - c'est-à-dire un clip papier IS == seulement à lui-même. == Tests identité , quel est égal à tests équivalence .

Vous pouvez avoir deux objets entiers distincts avec un 0 en eux (ils sont égaux () ); La mise en cache signifie sauvegarder des objets et les réutiliser lorsque cela est possible.


0 commentaires

1
votes

Ce que vous appelez "EQUIPE EGAL" est identité : deux références (i.e. objets) sont identiques si elles sont les mêmes cas. Si vous savez quels pointeurs sont dans d'autres langues, vous pouvez comparer l'identité à l'égalité du pointeur.

Ce que vous appelez "profond égal" est égalité : deux objets a et b sont égaux si a.equaux (b ) retourne true (et espérons-le vice versa). L'exactitude de l'égalité dépend fortement de la manière dont la méthode est implémentée. Voir le Javadoc de la classe Classe pour plus de détails.


0 commentaires

2
votes

premier off: neuf entier (0) == neuf entier (0) sera jamais évaluer à vrai , comme neuf TOUJOURS crée un nouvel objet, évacuer tout mécanisme de mise en cache d'autoboxage qui pourrait exister.

Qu'est-ce que vous avez probablement entendu parler de l'autoboxage (c'est-à-dire une conversion automatique de valeurs primitives sur leurs classes d'emballage respectives si nécessaire). L'autoboxage utilise un mécanisme également accessible à l'aide des classes de wrapper ValueOf () Méthodes. En d'autres termes: Boxing automatique An int à un Integer fonctionne à peu près la même chose que l'appelant integer.valueof (int) .

INTEGER.Valueof (0) == INTEGER.VALUEOF (0) EVALUER à TRUE , car les valeurs communes (c.-à-d. une faible valeur absolue) sont en cache. Vous obtiendrez la idem integer objet lorsque vous appelez valueof (0) deux fois de suite. Ce n'est pas nécessairement vrai avec des valeurs plus élevées (telles que 666 dans votre exemple).


0 commentaires

6
votes

Eh bien, réellement la dissection peu profonde / profonde est différente de == / dissection égale:

  1. == se compare pour l'identité d'objet, c'est-à-dire que vous vérifiez si les opérandes sont les mêmes en fait (deux références à la même zone de mémoire), alors que est égal à code> se compare pour l'objet l'équivalence, la valeur "logique" de deux, éventuellement pas identique les objets sont les mêmes. Si pour deux Objets P>

    a.equals(b) // if a != null
    
  2. La distinction peu profonde / profonde a du sens seulement pour est égal à la comparaison code>. Peu profond signifie que vous comparez seulement Contenu immédiat de deux objets à trouver si ils "égaux" dans votre sens, alors que profond signifie que vous comparer le contenu de vos objets récursivement jusqu'à ce que vous avez besoin de comparer est des champs primitifs. Si Vous définissez égale code> méthode de votre objets comme séquence d'appels vers est égal à code> dans les champs d'instance de ces objets, vous utilisez une comparaison profonde. Si Vous définissez égale code> à l'aide de == code> opérateur comparer les types de composés, comme des chaînes, alors vous utilisez une comparaison peu profonde - et c'est incorrect dans Java. Li> ol>

    moral de tout cela est que vous ne devez jamais utiliser == code> pour comparer deux objets composés, sauf si vous les considérez égal uniquement si elles sont identiques. P>


1 commentaires

Ce que vous dites est vrai, mais il semble que le conférencier utilisait "peu profond" pour signifier une identité de référence et "profonde" à une équivalence moyenne. La logique est certainement sain.