In che modo il metodo toString()
, l'operatore ==
e il metodo equals()
funzionano in modo diverso o simile sui tipi di riferimento e primitivi?In che modo i metodi dell'oggetto toString(), ==, equals() funzionano in modo diverso o simile sui tipi di riferimento e primitivi?
risposta
Per i tipi di riferimento, == confronta il riferimento effettivo (in cui si trova l'oggetto in memoria) dove il metodo equals esegue un confronto dei dati.
La JVM a volte "String intern" le stringhe immutabili per motivi di prestazioni. Causando questo:
String a = "abc";
String b = "abc";
if (a == b){
//The if statement will evaluate to true,
//if your JVM string interns a and b,
//otherwise, it evaluates to false.
}
L'operatore '==' lavora sul tipo primitivo che hai, che nel caso di oggetti di riferimento è il riferimento stesso. Quello è a == b
confronterà i valori per i tipi primitivi come int, ma confronterà il riferimento (non il valore) per i tipi di riferimento. Due oggetti di tipo di riferimento che non sono uguali ma hanno lo stesso valore restituiscono true
quando viene chiamato il metodo equals()
, ma a == b
sarà falso.
Per i tipi primitivi, quando si chiama un metodo, il tipo viene precedentemente convertito (in box) in un tipo di riferimento e quindi viene chiamato il metodo. Ciò significa che per i tipi primitivi a == b
si otterrà lo stesso valore di a.equals(b)
, ma in quest'ultimo caso verranno creati due oggetti box temporanei prima di chiamare il metodo equals()
. Ciò renderà l'operazione più costosa in termini di tempo della CPU, il che può o meno rappresentare un problema a seconda di dove accade.
Vale a dire, per confrontare i valori di tipo primitivo è necessario utilizzare ==
, mentre per confrontare i valori del tipo di riferimento è necessario utilizzare il metodo .equals()
.
Lo stesso accade con il metodo toString()
. Quando viene chiamato su un oggetto del tipo di riferimento, chiamerà il metodo appropriato e produrrà una stringa. Quando viene richiamato un tipo primitivo, il tipo verrà autoboxato e quindi il metodo verrà chiamato nell'oggetto temporaneo. In questo caso, è possibile chiamare il metodo statico toString()
appropriato (ad esempio, per la chiamata interna Integer.toString(myint)
) per evitare di creare l'oggetto temporaneo.
'a.equals (b)' non verrà compilato se 'a' è un tipo primitivo. – ajb
Per i tipi regolari (tra cui String):
==
confronta riferimenti a oggetti. Verifica se due riferimenti a oggetti sono uguali; cioè se si riferiscono allo stesso oggetto.equals(Object)
test se questo oggetto è "uguale a" un altro. Cosa significa "uguale a" dipende da come la classe dell'oggetto definisce l'uguaglianza. La classejava.lang.Object
definisceequals(other)
comethis == other
, ma molte classi sovrascrivono questa definizione.toString()
fornisce una conversione semplice dell'oggetto a una stringa. Il formato e il contenuto della stringa risultante sono specifici della classe e (dal punto di vista del contrattojava.lang.Object
) non ci sono garanzie che sia significativo.
Per (true) tipi primitivi:
==
confronta valori del tipo, eequals()
etoString()
non sono definiti. Java non consente di chiamare un metodo su un valore primitivo.
Tuttavia, questo è complicato dal fatto che in alcuni contesti linguaggio Java dice che un tipo primitivo può essere "autoboxed" per dare un esempio di tipo corrispondente involucro del tipo primitivo; per esempio. int
corrisponde a java.lang.Integer
e così via. Per le classi involucro:
==
è definita la stessa come per qualsiasi altro tipo di riferimento,equals()
confronta i valori avvolti, etoString()
formatta i valori avvolto.
Il bastone tra le ruote è illustrata dal seguente:
int a = ...
int b = a;
Integer aa = a; // autoboxing occurs
Integer bb = b; // autoboxing occurs
assert a == b; // always succeeds
assert aa.equals(bb); // always succeeds
assert aa == bb; // sometimes succeeds, sometimes fails.
La ragione per cui l'ultimo a volte fallisce è che la JLS non garantisce che autoboxing un dato valore di base darà sempre lo stesso involucro oggetto. Sarà in alcuni casi (ad esempio per i numeri interi piccoli) e non per gli altri (ad esempio i grandi numeri interi).
La lezione da trarre dall'esempio sopra riportato è che bisogna fare molta attenzione all'utilizzo di ==
su un tipo di riferimento. Utilizzatelo solo quando si in realtà si desidera verificare se due riferimenti si riferiscono allo stesso oggetto. Non usarlo se vuoi solo verificare se gli oggetti sono "uguali" senza il sovraccarico di chiamare equals()
.
(Si noti inoltre che String
è un altro tipo in cui ==
sta per dare la risposta sbagliata in molte situazioni, vedi How do I compare strings in Java?.)
'==' sulle primitive controlla solo i valori e ignora i tipi. 'int x = 5; lunga y = 5L; byte b = 5; x == y; b == x; 'Entrambi restituiscono true. – arun
Non sta "ignorando" i tipi. Uno o l'altro degli operandi viene promosso al tipo dell'altro. Inoltre, ho detto "valori del tipo" ... –
- 1. In che modo i puntatori funzionano con i tipi primitivi in Java?
- 2. C'è un modo per creare tipi nominali in TypeScript che estendono i tipi primitivi?
- 3. Come inviare multimetod sui tipi primitivi?
- 4. Genera test unitari per i metodi hashcode, equals e toString
- 5. Perché == operatore ed equals() comportarsi in modo diverso per i valori di AnyVal a Scala
- 6. isAssignableFrom con tipi di riferimento e primitivi
- 7. In che modo respond_to e respond_with funzionano nei binari?
- 8. Quali sono i metodi dinamici e in che modo DynamicMethod è diverso da MethodBuilder?
- 9. In che modo il framework dell'editor GWT 2.1 supporta i tipi primitivi?
- 10. Le enumerazioni Java sono considerate tipi primitivi o di riferimento?
- 11. In che modo i tipi di dattilografo toccano in vi?
- 12. Perché setattr funziona in modo diverso per attributi e metodi?
- 13. Generazione di equals/hashcode/toString tramite annotazione
- 14. In che modo i programmi/compilatori/interpreti clojure effettivamente "funzionano"?
- 15. I puntatori sono tipi primitivi in C++?
- 16. Perché Linq si unisce in modo diverso
- 17. Chrome genera i CSS in modo diverso online o offline?
- 18. Perché '::' e '->' funzionano (ordinariamente) in modo intercambiabile quando si chiamano i metodi dai moduli Perl?
- 19. In che modo rendering render @users e render 'new' diverso?
- 20. In che modo Apache httpd e Tomcat funzionano insieme?
- 21. I tipi di dati primitivi thread-safe in Java
- 22. Perché i collegamenti [class.someClass] e [ngClass] funzionano in modo diverso con myObservable $ | async?
- 23. Qual è la differenza tra i tipi primitivi e di riferimento?
- 24. In che modo PHP, Symlink e __FILE__ funzionano bene insieme?
- 25. In che modo Object.prototype.toString.apply (valore) è diverso da value.toString()?
- 26. In che modo Inheritance e JAXB funzionano insieme?
- 27. Utilizzo di tipi primitivi con ClassLoader
- 28. In che modo la cache "Priorità" e "AbsoluteExpiration" funzionano insieme?
- 29. In che modo funzionano JavaScript Math.max e Math.min?
- 30. In che modo "Typemock Isolator" simula i metodi statici?
imparato un nuovo concetto - internato! – lft93ryt