Jaki jest akceptowany styl używania słowa kluczowego `this` w Javie?

37

Pochodzę z języków takich jak Python lub Javascript (i innych, które są mniej zorientowane obiektowo) i staram się poprawić moją praktyczną znajomość Javy, którą znam tylko powierzchownie.

Czy uważanie thisza wcześniejsze atrybuty instancji jest uważane za złą praktykę ? Pisanie jest dla mnie bardziej naturalne

...
private String foo;

public void printFoo() {
    System.out.println(this.foo);
}
...

niż

...
private String foo;

public void printFoo() {
    System.out.println(foo);
}
...

ponieważ pomaga mi to odróżnić atrybuty instancji od zmiennych lokalnych.

Oczywiście w języku takim jak Javascript sensowniej jest zawsze używać this, ponieważ można mieć więcej funkcji zagnieżdżania, stąd lokalne zmienne pochodzące z większych zakresów. O ile rozumiem w Javie, takie zagnieżdżanie nie jest możliwe (z wyjątkiem klas wewnętrznych), więc prawdopodobnie nie jest to duży problem.

W każdym razie wolałbym użyć this. Czy byłoby to dziwne i nie idiomatyczne?

Andrea
źródło
Używamy narzędzia do promowania tego w naszej firmie. Narzędzie przepisuje kod z naszym bez tego, w zależności od polityki firmy. Tak więc wszyscy kodują, jak im się podoba, a kod jest formatowany we właściwy sposób w czasie zatwierdzania.
deadalnix,
2
„ponieważ można zagnieżdżać więcej funkcji, stąd zmienne lokalne pochodzą z większych zakresów”. Ponadto fakt, że „to” nie jest w rzeczywistości jednym z miejsc, z których może pochodzić niekwalifikowana zmienna w funkcji JS.
Random832,
2
Wszystkie zmienne instancji poprzedzam znakiem podkreślenia, dzięki czemu mogę łatwo odróżnić zmienne lokalne i zmienne instancji bez użycia this.
WuHoUnited
4
W C # StyleCop chce, abyś wstawiał this.odniesienie do zmiennych składowych , metod itp. Podoba mi się, zgadzam się z tą regułą. Myślę, że to jest lepsze niż nazywanie czegoś znakiem podkreślenia na początku. Postępowałbym zgodnie z tą samą zasadą, gdybym kodował w Javie.
Job

Odpowiedzi:

40

W większości IDE możesz po prostu najechać kursorem na zmienną, jeśli chcesz wiedzieć. Ponadto naprawdę, jeśli pracujesz w metodzie instancji, powinieneś naprawdę znać wszystkie zaangażowane zmienne. Jeśli masz ich zbyt wiele lub ich nazwy kolidują, musisz zrefaktować.

To naprawdę dość zbędne.

DeadMG
źródło
7
Ponadto: rozsądne IDE powinno wizualnie odróżniać pola i lokalne zmienne / parametry. Na przykład w środowisku Eclipse (domyślnie) pola są niebieskie, a zmienne lokalne są czarne.
Joachim Sauer
1
@ Joachim Fajny punkt, Eclipse może nawet zmieniać parametry kolorów i zmienne lokalne inaczej, jeśli użytkownik tego chce (jednak nie jest to domyślnie).
Eric-Karl,
3
Chociaż się zgadzam, kiedy napotykam kod innych programistów (i chociaż na pierwszy rzut oka jestem obcy), uważam, że this.jest o wiele bardziej pomocny. Jest tak również prawdopodobnie dlatego, że nie mam IDE, które inaczej koduje kolory zmiennych lokalnych / obiektowych.
Brad Christie,
3
+1 za (parafrazę) „refaktor, jeśli musisz użyć tego, aby wydedukować, że jest on członkiem”. Właśnie to chciałem podkreślić.
Yam Marcovic
Nie uważam, że utrudnia to czytanie, aw zamian kod pozostaje czytelny w edytorach, które mają mniej wyrafinowane podświetlanie składni, które nie rozróżniają pól i miejscowych. Zawsze miałem opinię, że powinieneś starać się, aby Twój kod był czytelny w najbardziej podstawowym edytorze tekstów, a jeśli nie jest, powinien istnieć dobry powód.
Kevin
26

Wolę używać this. Ułatwia odczyt kodu w różnych edytorach, które w ten sam sposób kolorują zmienne lokalne i instancyjne. Ułatwia także odczytywanie kodu na wydrukowanej stronie podczas czegoś takiego jak przegląd kodu. Jest to również dość mocne przypomnienie o zakresie zmiennej dla innych programistów.

Istnieją jednak argumenty przeciwko temu. We współczesnych IDE możesz dowiedzieć się o zasięgu zmiennej, najeżdżając na nią lub oglądając ją w strukturze drzewiastej. Możesz także zmienić kolor i / lub czcionkę zmiennych w zależności od ich zakresu (nawet w taki sposób, że po wydrukowaniu widać, jaki jest zakres zmiennej).

Wierzę, że ostatnie zdanie ChrisF jest martwe: bądź konsekwentny w swoim użyciu.

Thomas Owens
źródło
7
„Jest to również dość mocne przypomnienie o zakresie zmiennej dla innych programistów”. - powód, dla którego zwykle używam i lubię widzieć this.w kodzie. Pisanie zajmuje pół sekundy i może zaoszczędzić długie minuty, gdy musisz dowiedzieć się, czy facet, przed którym naprawdę chciałeś użyć właściwości pascal-case zamiast lokalnej skrzynki na wielbłądzie, kiedy dokonał ostatniej zmiany w ostatniej chwili 20 wersji temu.
scrwtp,
18

Jednym z miejsc, w których konsekwentnie używam „tego”, są setery i / lub konstruktorzy:

public void setFoo(String foo) {
    this.foo = foo;
}

Poza tym nie uważam za konieczne, aby to dodać. Czytając treść metody, parametry i miejscowi są na miejscu - i dość łatwo je śledzić (nawet bez pomocy IDE). Również lokale i pola mają różną naturę (stan obiektu vs. przechowywanie lub parametr przejściowy).

Jeśli istnieje jakieś zamieszanie dotyczące tego, co jest zmienną, a co jest polem, prawdopodobnie oznacza to, że metoda ma zbyt wiele zmiennych / parametrów, jest zbyt długa i zbyt złożona i powinna zostać uproszczona.

Jeśli zdecydujesz się użyć „tego” do oznaczania pól, polecam upewnić się, że konwencja jest zawsze ściśle przestrzegana - naprawdę łatwo byłoby założyć, że nie „to” oznacza, że ​​jest to lokalny i łamie rzeczy w oparciu o założenie.

edytuj: Używam tego również w równości, klonowaniu lub cokolwiek, co ma parametr „tego” tego samego typu obiektu:

public boolean isSame(MyClass that) {
    return this.uuid().equals(that.uuid());
}
ptyx
źródło
8

To jest dyskusyjne.

Biorąc C # jako analogię, ponieważ ma bardzo podobną składnię i strukturę jak Java, okazuje się, że C # StyleCop ma domyślną regułę, która nalega, abyś dodał this, ale ReSharper ma domyślną regułę, która mówi, że thisjest nadmiarowa (którą jest) i może być oddalony.

Więc jeśli używasz jednego narzędzia, dodasz je, ale jeśli używasz innego, usuniesz je. Jeśli korzystasz z obu narzędzi, musisz wybrać i wyłączyć jedną z reguł.

Jednak zasady oznaczają, że konsekwentnie korzystasz - co jest prawdopodobnie najważniejszą rzeczą.

ChrisF
źródło
8

Czy uważa się za złą praktykę zawsze dodawanie tego do atrybutów bieżącej instancji?

Tak - przez niektórych, nie - przez innych.

Lubię i używam thissłowa kluczowego w moich projektach w Javie i C #. Można argumentować, że IDE zawsze podświetla parametry i pola innym kolorem, jednak nie zawsze pracujemy w IDE - musimy wykonać wiele scaleń / różnic / szybkich zmian w notatniku / sprawdzić fragmenty kodu w wiadomości e-mail . O wiele łatwiej jest mi dostrzec od pierwszego spojrzenia, gdzie zmienia się stan instancji - na przykład, aby przejrzeć niektóre możliwe problemy dotyczące współbieżności.

Andrey Taptunov
źródło
7

Myślę, że jeśli musisz tego użyć, albo masz metodę, która jest za długa, albo klasę, która próbuje zrobić za dużo, albo jedno i drugie.

Metody nigdy nie powinny być dłuższe niż kilka wierszy kodu, należy używać jednej lub dwóch zmiennych lokalnych, określając, co staje się łatwe; nawet z kontekstem 3-liniowym większości narzędzi do porównywania. Jeśli twoje metody są zbyt długie, a twoje klasy mają zbyt wiele obowiązków (często oznaczających zbyt wiele pól), rozwiązaniem jest ich podzielenie.

Myślę, że „to” po prostu zaśmieca kod. Zwłaszcza w przypadku nowoczesnych IDE, które będą inaczej kolorować parametry lokalne / zmienne lokalne / pola.

Eric-Karl
źródło
5

Myślę, że odpowiedziałeś na swoje pytanie w ten sposób:

Pisanie jest dla mnie bardziej naturalne

... this.foo ...

niż

... bla ...

ponieważ pomaga mi to odróżnić atrybuty instancji od zmiennych lokalnych.

Jeśli są bardziej wygodne przy użyciu this.jednocześnie poprawiając swoją wiedzę z języka Java, a następnie przez wszystkie środki użyć coś ( myślę, że to, w pewnym sensie, znajomy Python siebie , że jesteś w odniesieniu do ).

Chodzi o to, że chociaż ludzie przedstawią solidne / stosowne argumenty dotyczące używania lub nieużywania this., nadal brzmi to jak debata, podany przykład:

  • sprawia, że ​​cel zmiennych jest jasny, a powinieneś przepisać kod, jeśli nie jest jasne, co to jest każda zmienna;
  • this.jest zbędny, jeśli spędzasz cały dzień w IDE vs. wykonuję recenzje kodu i robię różnice w różnych wersjach za pomocą komparatora bez podświetlania składni;
  • brak pisania daje this.mi milisekundy produktywności w porównaniu do tego, że this.płacę za naciśnięcie klawisza, a dodawanie jest jak podwyżka: D;
  • itd itd

Ale najważniejsze jest to, że pod koniec dnia nadal wraca do osobistych preferencji i środowiska pracy .


źródło
5

Zwykle dodanie tego nie jest konieczne. Nie sądzę, że jest to zła praktyka per se, ale nadmierne użycie tego byłoby prawdopodobnie uważane za niezwykłe w większości baz kodu Java, które widziałem.

Uważam jednak, że jest cenny w kilku konkretnych sytuacjach:

Przesłanianie parametrów lokalnych - czasem konieczne jest określenie, że chcesz użyć zmiennej instancji zamiast parametru / zmiennej lokalnej o tej samej nazwie. Jest to dość powszechne w konstruktorach, w których chcesz, aby nazwa parametru była zgodna z nazwą wewnętrzną zmiennej instancji, której używa się do inicjalizacji np.

class MyObject {
  int value;

  public MyObject(int value) {
    this.value=value;
  }
}

Podczas obsługi innych instancji tej samej klasy - uważam, że dzięki temu kod jest jaśniejszy i bardziej zrozumiały, ponieważ pozwala wyraźnie określić, do której instancji klasy się odwołujesz, np.

class MyObject {
  int value;
  ....

  public MyObject add(MyObject other) {
    return new MyObject( this.value + other.value )
  }
}
mikera
źródło