2015-09-09 15 views
11

Ho notato che chiamare equals(""); in un metodo di una classe non genera alcun errore entro Eclipse. Non ho mai visto .equals chiamato senza qualcosa come string1.equals(string2);.Chiamata uguale (""); da solo compila e corre

package voodoo; 

public class Equals { 

    public void method(){ 
     equals(""); 
    } 

} 

Che cosa sta succedendo qui e quando sarebbe chiama equals() di per sé mai essere utilizzato?

Se lo metto in un JUnit da testare, viene eseguito e trasmesso.

+3

@WOUNDEDStevenJones: Perché pensi che? –

+0

Non c'è niente di sbagliato in questa funzione: 'public void answerToLifeTheUniverseAndEverything() {42; } '. Quel 42 è lasciato cadere sul bit floor, proprio come il tuo 'equals (" ")'. –

+2

@DavidHammen Non verrà compilato. Le espressioni arbitrarie sono dichiarazioni valide in C++ [ma non in Java] (https://stackoverflow.com/questions/32406041/when-is-an-unassigned-expression-a-valid-statement). – Boann

risposta

16

equals che si sta chiamando è equals metodo Object s', che può essere chiamato il this riferimento senza specificare in modo esplicito. In altre parole, la chiamata è equivalente a

this.equals(""); 

Ciò è perfettamente valido, anche se un'implementazione ben educato deve sempre ritornare false. Si noti che il valore di ritorno viene ignorato, che è anche legale.

Si può vedere cosa sta succedendo sovrascrivendo equals con qualcosa che stampa un messaggio, per una questione di un esperimento:

public class Equals { 

    public void method(){ 
     equals(""); 
    } 
    @Override 
    public boolean equals(Object other) { 
     System.out.println("I am being compared to '"+other+"'"); 
     return super.equals(other); 
    } 
} 
+1

"un'implementazione ben educata deve sempre restituire false". Veramente? Non riesco a creare la mia migliorata classe di stringhe (magari con codifiche extra) e consentirne il confronto con le stringhe normali? Solo per il gusto dell'argomento;) – LS97

+9

@ LS97 Interromperà il [requisito di simmetria] (http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals (java. lang.Object)), perché 'java.lang.String' restituire' false' per tutto ciò che non è un 'java.lang.String', e non è possibile creare una sottoclasse di' java.lang.String' perché la classe è 'finale'. – dasblinkenlight

+0

OK, non sapevo del 'finale'. Credo che dovrei fare la mia lettura. – LS97

5

Poiché tutto è sottoclasse di classe Object, qui si chiama il metodo di classe super (Object) uguale. E riceve Object come parametro dove "" è un oggetto stringa, esso va bene.

E restituisce boolean effettivamente, ma si sta ignorando per ricevere. È legale ignorare il risultato.

Se lo si riceve e si seleziona, restituisce false poiché la classe Equals non è uguale a una stringa vuota.

6

equals non è statico e chiama equals di Object che è simile a qualsiasi altro metodo della classe. Inoltre, la nostra classe è figlia di Object. La chiamata al metodo è qualcosa come thisObject.equals(emptyString) note qui String è anche un Object. Quindi, in definitiva, stiamo invocando il metodo currntObject.equals(object) dal figlio di Object.

E 'simile a,

class A { 
    public boolean ok(Object str) { 
     return false; 
    } 
} 

class B extends A { 

    public void method(){ 
     ok(""); 
    } 
} 

Qui bambino non ha sovresposta il equals così, chiamerà il metodo del suo genitore e si farà riferimento all'istanza corrente.

3

equals(...) senza oggetto esplicito chiama il metodo su this. Nel tuo esempio stai confrontando l'istanza di Equals con una stringa vuota.

2

Il metodo pubblico equals() alla classe Object. Tutta la classe per impostazione predefinita una classe figlio diretta/indiretta della classe Object. La tua classe Equals non eredita alcuna classe in modo esplicito. Quindi è una sottoclasse diretta di Object.

E nella classe Object metodo equals() è dichiarato come questo -

public boolean equals(Object obj){} 

Quindi il codice è completamente valida. In effetti stai chiamando Equals.equals() allo method().

Problemi correlati