2015-09-09 8 views
11

Zauważyłem, że wywołanie equals(""); w metodzie klasy nie generuje żadnego błędu w obrębie Eclipse. Nigdy nie widziałem .equals wywoływana bez czegoś takiego jak string1.equals(string2);.Wywołanie równości (""); sam się kompiluje i uruchamia

package voodoo; 

public class Equals { 

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

} 

Co tu się dzieje i kiedy dzwoni equals() przez siebie nigdy być używane?

Jeśli to przetestuję, przetestuję i przejdzie.

+3

@WOUNDEDStevenJones: Dlaczego tak myślisz? –

+0

Nie ma nic złego w tej funkcji, albo: 'public void answerToLifeTheUniverseAndEverything() {42; } '. Że 42 jest upuszczone na podłodze bitów, tak jak twoje "równa się (" ")'. –

+2

@DavidHammen Nie skompiluje się. Wyrażenia arbitralne są poprawnymi instrukcjami w C++ [ale nie w Javie] (https://stackoverflow.com/questions/32406041/when-is-an-unassigned-expression-a-valid-statement). – Boann

Odpowiedz

16

equals że dzwonisz jest equals metoda Object „s, która może być wywołana na this odniesienia bez określania go wyraźnie. Innymi słowy, wywołanie jest równoważne

this.equals(""); 

To jest całkowicie poprawny, choć dobrze ułożona realizacja musi zawsze powrócić false. Zwróć uwagę, że zwracana wartość jest ignorowana, co również jest legalne.

Można zobaczyć, co się dzieje nadrzędnymi equals z czymś, co drukuje wiadomość, jako przedmiot eksperymentu:

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

"dobrze zachowana implementacja musi zawsze zwracać fałsz". Naprawdę? Czy nie mogę utworzyć własnej ulepszonej klasy ciągów (być może z dodatkowymi kodowaniami) i pozwolić na porównanie jej z normalnymi ciągami? Tylko ze względu na argumenty;) – LS97

+9

@ LS97 To by złamać [wymaganie symetrii] (http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals (java. lang.Object)), ponieważ 'java.lang.String' zwróci' false' dla niczego, co nie jest 'java.lang.String', i nie jest możliwe stworzenie podklasy' java.lang.String' ponieważ klasa jest "ostateczna". – dasblinkenlight

+0

OK, nie wiedziałem o "ostatecznym". Chyba powinienem zrobić moje czytanie. – LS97

5

Ponieważ wszystko jest podklasą klasy Object, tutaj nazywa się metodę super klasy (Object) równa się. I otrzymuje obiekt jako parametr, w którym "" jest obiektem typu string, kompiluje się dobrze.

W rzeczywistości zwraca ona boolean, ale ignorujesz to, aby otrzymać. Legalne jest ignorowanie wyniku.

Jeśli ją otrzymasz i sprawdzisz, to zwróci ona false, ponieważ twoja klasa Equals nie jest równa pustemu ciągowi znaków.

6

equals jest niestatyczna i wywołuje equals z Object, która jest podobna do wywoływania dowolnej innej metody klasy. Ponadto nasza klasa jest dzieckiem Object. Wywołanie metody jest podobne do tego, jak thisObject.equals(emptyString) tutaj String jest także Object. Tak więc, ostatecznie, wywołujemy metodę currntObject.equals(object) od potomka Object.

Jest podobny do

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

class B extends A { 

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

Tu dziecko nie został nadpisaneequals tak, to wywołać metodę na jego rodzic i będzie odnosić się do bieżącej instancji.

3

equals(...) bez wyraźnej obiektu wywołuje metodę na this. W twoim przykładzie porównujesz wystąpienie Equals z pustym łańcuchem.

2

Metoda publiczna w klasie Object. Cała klasa domyślnie jest klasą potomną bezpośrednią/pośrednią klasy Object. Twoja klasa Equals nie dziedziczy bezpośrednio żadnej klasy. Więc jest to bezpośrednia podklasa Object.

A w klasie Object metoda equals() deklaruje tak -

public boolean equals(Object obj){} 

Więc kod jest całkowicie poprawny. W rzeczywistości dzwonisz pod numer Equals.equals() pod adresem method().