Innymi słowy, dlaczego potrzebujesz inicjatora instancji? Jaką różnicę lub przewagę masz w pisaniu inicjatora instancji nad konstruktorem?
Innymi słowy, dlaczego potrzebujesz inicjatora instancji? Jaką różnicę lub przewagę masz w pisaniu inicjatora instancji nad konstruktorem?
Odpowiedzi:
To wydaje się dobrze to wyjaśniać:
Inicjatory instancji są użyteczną alternatywą dla inicjatorów zmiennych instancji, gdy:
kod inicjujący musi przechwytywać wyjątki lub
wykonywać wymyślne obliczenia, których nie można wyrazić za pomocą inicjatora zmiennej wystąpienia. Oczywiście zawsze można by taki kod napisać w konstruktorach.
Ale w klasie, która miała wiele konstruktorów, musiałbyś powtórzyć kod w każdym konstruktorze. Dzięki inicjalizatorowi instancji możesz po prostu napisać kod raz, a zostanie on wykonany bez względu na to, jaki konstruktor zostanie użyty do utworzenia obiektu. Inicjatory instancji są również przydatne w anonimowych klasach wewnętrznych, które w ogóle nie mogą deklarować żadnych konstruktorów.
Pod względem cyklu życia obiektu nie ma różnicy. Oba są wywoływane w czasie konstrukcji i logicznie rzecz biorąc, blok inicjalizatora można uznać za część konstrukcji.
Z semantycznego punktu widzenia inicjator jest dobrym narzędziem z kilku powodów:
inicjalizator może poprawić czytelność kodu, utrzymując logikę inicjalizacji obok inicjowanej zmiennej:
public class Universe {
public int theAnswer;
{
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
}
// a bunch of other vars
}
vs
public class Universe {
public int theAnswer;
// a bunch of other vars
public Universe() {
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
// other constructor logic
}
}
Inicjatory są wywoływane niezależnie od tego, który konstruktor jest używany.
Inicjatory mogą być używane w anonimowych klasach wewnętrznych, w których konstruktorzy nie mogą.
theAnswer
to zadeklarowana zmienna instancji. Jest inicjowany w anonimowym bloku inicjalizatora. Zwróć uwagę na średnik po deklaracji zmiennej.
Jeśli masz wiele konstruktorów i chcesz, aby jakiś wspólny kod był wykonywany dla każdego konstruktora, możesz użyć inicjatora instancji, ponieważ jest on wywoływany dla wszystkich konstruktorów.
Generalnie unikałbym idiomu inicjatora instancji - jedyną prawdziwą zaletą, jaką daje on w porównaniu z inicjatorami zmiennych, jest obsługa wyjątków.
A ponieważ metoda init (wywoływana z konstruktora) może również obsługiwać wyjątki, a także centralizuje kod konfiguracji konstruktora, ale ma tę zaletę, że może działać na wartościach parametrów konstruktora, powiedziałbym, że inicjator wystąpienia jest nadmiarowy i dlatego powinien być unikać.
Prawdziwa zaleta instancji inicjalizatorów ponad konstruktorów jest widoczne, gdy używamy anonimowej klasy wewnętrznej .
Anonimowe klasy wewnętrzne nie mogą mieć konstruktora (ponieważ są anonimowe) , więc są całkiem naturalne, np . Inicjalizatory .
W momencie tworzenia obiektu, jeśli chcemy wykonać inicjalizację zmiennych instancji, to powinniśmy wybrać Konstruktor, poza czynnością inicjalizacyjną, jeśli chcemy wykonać jakąkolwiek czynność w momencie tworzenia obiektu to na przykład blok.
Nie możemy zastąpić konstruktora blokiem instancji, ponieważ konstruktor może przyjmować argumenty, ale blok instancji nie może przyjmować argumentów.
Nie możemy zastąpić konstruktora bloku wih instancji, ponieważ klasa może zawierać więcej niż jeden konstruktor. Jeśli chcemy zastąpić blok instancji konstruktorem, to w każdym konstruktorze musimy napisać kod blokowy instancji, ponieważ w czasie wykonywania nie możemy się spodziewać, który konstruktor zostanie wywołany, niepotrzebnie zwiększy zduplikowany kod.
Przykład:
class MyClass{
static int object_count = 0;
MyClass(){
object_count++;
}
MyClass(int i){
object_count++;
}
void getCount() {
System.out.println(object_count);
}
public static void main(String... args) {
MyClass one = new MyClass();
MyClass two = new MyClass(2);
two.getCount();
}
}
Wynik : 2
class MyClass{
static int object_count = 0;
{
object_count++;
}
MyClass(){
}
MyClass(int i){
}
void getCount() {
System.out.println(object_count);
}
public static void main(String... args) {
MyClass one = new MyClass();
MyClass two = new MyClass(2);
two.getCount();
}
}
Wynik : 2
Inicjator jest sposobem udostępniania kodu między konstruktorami i sprawia, że kod jest bardziej czytelny, jeśli inicjator jest używany z deklaracją zmiennej.
Kompilator Java kopiuje bloki inicjalizatora do każdego konstruktora. Dlatego to podejście może służyć do udostępniania bloku kodu między wieloma konstruktorami. Dokumentacja Oracle