Sposób 2 jest lepszy, ponieważ zapewnia jednolity sposób ustawiania wartości zmiennej. Ale wiąże się to z ryzykiem, ponieważ wywołujesz metodę nadpisującą w konstruktorze. Więc prawo składni używa ostatecznego słowa kluczowego:
public final void setField(int field){
this.field = field;
}
//way 2
public A(int field){
setField(field);
}
Z final
metoda nie zostaną nadpisane. Jeśli nie możesz sobie pozwolić na ostateczną metodę, nie wywołuj regulatora w konstruktorze. Ale zwykle dziwne jest przesłonięcie setera.
To jest dobre, bo może chcesz zmienić setter później:
- kontrole dodawania argument i rzucić
IllegalArgumentException
razie potrzeby.
- Dodaj licznik
- Informuj obserwatorów (w obserwowalnych wzorzec)
- sprawiają, że blok synchronizowany zapewnić wątku bezpieczeństwa
- ...
i trzeba będzie to zrobić w jedno miejsce. Jest to realizacja DRY principle.
public final synchronized void setField(int field){
if (0 <= field && field <= MAX_VALUE) {
this.field = field;
} else {
throw new IllegalArgumentException();
}
}
//still has all the benefits of setter
public A(int field){
setField(field);
}
A = new A(-1) //throws IllegalArgumentException
Nie martw się o optymalizacji i kosztach metody dodatkowego wezwania. JVM zazwyczaj może zoptymalizować taki kod poprzez inlinowanie metod.
To, co tak naprawdę sprawia, że rozwój jest wolniejszy, to szukanie błędu. Ta metoda pomaga zmniejszyć liczbę błędów i łatwiej utrzymać kod.
Ale czy inwokacja nie jest metodą wolniejszą? – Aero
Mam to. Dziękuję Ci. – Aero
Może występować zagrożenie bezpieczeństwa wywoływania publicznej metody zastępowania wewnątrz konstruktora – dkatzel