Risolto Java equals() selezione

OliWan

Utente Bronze
15 Luglio 2022
20
15
0
23
In Java, se provo a do.equals() su una stringa nulla, viene emesso un errore di puntatore nullo. Mi chiedo se posso eseguire quanto segue se sto tentando di confrontare se una stringa è uguale a una stringa costante:
Codice:
MY_CONSTANT_STRING.equals(aStringVariable)
Sono sicuro che funzionerà, ma è semplicemente un codice estremamente pessimo?
Questo è un idioma Java comune noto colloquialmente come una condizione Yoda. Personalmente, preferisco gestire direttamente la situazione nulla, ma il metodo Yoda è ampiamente utilizzato e qualsiasi programmatore Java competente dovrebbe capire rapidamente cosa sta succedendo. Come devo procedere?
 
Senza scomodare Yoda, non potresti usare l'operatore == ? aStringVariable == MY_CONSTANT_STRING
Altrimenti non vedo alcun problema a farlo in quel modo.
 
Ultima modifica:
I think the yoda style is usually a bad idea.
Java:
string.equals("literal"); // normal style
"literal".equals(string); // yoda style
You should remember that we are talking about objects; thus, these two lines are semantically different. If string is null, the first line throws a NullPointerException while the second line evaluates to false. In "normal style" the second line is roughly equivalent to
Java:
string != null && string.equals("literal"); // short-circuit evaluation
Sometimes this is not what you wanna do. In many common scenarios you are (implicitly) asserting that the string is not null. For example, you might have something like String string = getInstalledVersion(); to read the version number of a different program (e.g., of your kernel) from a file and you really expect that string to be there. In this scenario, a null string would be something (you think!) impossible to happen and this is exactly the case where throwing an exception (something is going wrong) is exactly what you wanna do.

In a different scenario, let's say you have something like String string = getLastVersion(); to fetch the last version number of your own program from the network. In this case you already expect that the user might have no access to the internet sometimes, so getLastVersion() returns null when the website is unreachable. In this case, assuming evaluating to false if the string is null is exactly what you want to do, the yoda condition might save you to write an explicit test. Technically speaking the yoda condition is slightly faster than its "roughly equivalent" version in normal style even though, in practice, this performance difference hardly measurable (especially in a language like Java). Most importantly, even if you really wanna squeeze every nanoseconds out of your program, I think you should comment your code to explain why "the yoda way is strong in that line" or you are gonna risk to introduce bugs while you refactor it.

Yoda conditions don't throw exceptions, but null is only seldomly considered to be a valid state for an object and clear is better than brief. The reason why null is only seldomly considered to be a valid state for an object is highlighted by the same guy who invented the null reference
I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. [Tony Hoare, Wikipedia]

PS. Ti ho risposto in inglese perché ho intuito che il tuo messaggio è un po' google traslato
:asd:

PPS. OliWan talking about yoda conditions is a curious coincidence.

Senza scomodare Yoda, non potresti usare l'operatore == ? aStringVariable == MY_CONSTANT_STRING
Non in java. In java le stringhe vanno confrontate attraverso un metodo, altrimenti vai a confrontare se i due oggetti hanno la stessa reference (se puntano alla stessa cosa).
 
Senza scomodare Yoda, non potresti usare l'operatore == ? aStringVariable == MY_CONSTANT_STRING
Altrimenti non vedo alcun problema a farlo in quel modo.
In Java le stringhe sono oggetti, quindi vengono creati nello heap, di conseguenza non puoi fare un semplice confronto tramite l'operatore "==", altrimenti andresti a confrontare soltanto le variabili riferimento che puntano a quei determinati oggetti (E' come fare un confronto tra puntatori, parlando in termini di C, dato che tu sei molto esperto in quel linguaggio). Di solito l'operazione che hai descritto si utilizza, in Java, per vedere se due riferimenti puntano allo stesso oggetto (anche se l'utilità pratica è pressoché nulla). Spesso capita di vedere nei programmi, tra le proprietà di una classe, le stringhe dichiarate come se fossero semplici variabili (es. "private String nome;"), ma in realtà si tratta di "zucchero sintattico" per semplificare la vita al programmatore. Inoltre, se non ricordo male, per confrontare le stringhe in Java c'è un metodo ancora più completo di equals(), ossia equalsIgnoreCase(): esso permette di confrontare le stringhe, a prescindere dalla dimensione dei caratteri (minuscolo, maiuscolo, con la prima lettera maiuscola e il resto minuscolo ecc.).
 
Avete ragione, dimenticavo che Java non supporta l'operator overloading, non usandolo quasi mai davo erroneamente per scontato che come molti altri linguaggi ad alto livello l'operatore == chiamasse in realtà la funzione di comparazione della classe string.
 
In Java, se provo a do.equals() su una stringa nulla, viene emesso un errore di puntatore nullo. Mi chiedo se posso eseguire quanto segue se sto tentando di confrontare se una stringa è uguale a una stringa costante:
Codice:
MY_CONSTANT_STRING.equals(aStringVariable)
Sono sicuro che funzionerà, ma è semplicemente un codice estremamente pessimo?
Questo è un idioma Java comune noto colloquialmente come una condizione Yoda. Personalmente, preferisco gestire direttamente la situazione nulla, ma il metodo Yoda è ampiamente utilizzato e qualsiasi programmatore Java competente dovrebbe capire rapidamente cosa sta succedendo. Come devo procedere?
Il modo yoda è il più utilizzato tra gli sviluppatori.
Ti permette di eseguire due controlli in uno (appunto il secondo è quello di verificare se l'oggetto con cui lo si sta confrontando, sia NULL), ti faccio qualche esempio:

Java:
static final String SUPREME_STRING = "Hello";
String s = null;

SUPREME_STRING.equals(s); // return false, perché 'Hello' NON è uguale a NULL - Yoda style

s.equals(SUPREME_STRING); // NullPointerException, poiché l'oggetto che stai usando per confronto, è NULL quindi non puoi usare i suoi metodi

s != null && s.equals(SUPREME_STRING); // return false, è un controllo valido e giusto, usando la variabile 's' come riferimento, ma con lo Yoda style, hai risparmiato un confronto

Se tu volessi utilizzare delle librerie per gestire le stringhe, c'è una libreria utilizzatissima chiamata Apache Commons Lang, che permette richiamando alcuni metodi statici di una classe, di effettuare alcuni controlli su stringhe passate in input, tipo se è NULL, oppure una stringa vuota, oppure se contiene solamente caratteri spazio ecc.
 
  • Mi piace
Reazioni: OliWan
Ultima modifica da un moderatore:
I think the yoda style is usually a bad idea.
Java:
string.equals("literal"); // normal style
"literal" .equals (string); // yoda style
You should remember that we are talking about objects; thus, these two lines are semantically different. If string is null, the first line throws a NullPointerException while the second line evaluates to false. In "normal style" the second line is roughly equivalent to
Java:
string != null && string.equals("literal"); // short circuit evaluation
Sometimes this is n't what you want to do. In many common scenarios you are (implicitly) asserting that the string is not null. For example, you might have something like String string = getInstalledVersion(); to read the version number of a different program (eg, of your kernel) from a file and you really expect that string to be there . In this scenario, a null string would be something (you think!) impossible to happen and this is exactly the case where throwing an exception (something is going wrong) is exactly what you wanna do.

In a different scenario, let's say you have something like String string = getLastVersion (); to fetch the last version number of your own program from the network. In this case you already expect that the user might have no access to the internet sometimes, so getLastVersion () returns null when the website is unreachable. In this case, assuming evaluating to false if the string is null is exactly what you want to do, the yoda condition might save you to write an explicit test. Technically speaking the yoda condition is slightly faster than its "roughly equivalent" version in normal style even though, in practice, this performance difference hardly measurable (especially in a language like Java).Most importantly, even if you really want to squeeze every nanosecond out of your program,

Yoda conditions don't throw exceptions, but null is only seldomly considered to be a valid state for an object and clear is better than brief. The reason why null is only seldomly considered to be a valid state for an object is highlighted by the same guy who invented the null reference


PS. I answered you in English because I sensed that your message is a bit google translated
: asd:

PS extension. OliWan talking about yoda conditions is a curious coincidence.


Not in java. In java strings must be compared through a method, otherwise go to compare if the two objects have the same reference (if they point to the same thing).
Thanks for the detailed answer! I got my answer.
And yeah it's a great coincidence :)