To jest ulubione pytanie do wywiadu . Na podstawie tych pytań ankieter próbuje dowiedzieć się, jak dobrze rozumiesz zachowanie obiektów w odniesieniu do konstruktorów, metod, zmiennych klas (zmiennych statycznych) i zmiennych instancji.
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test() {
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public void setFoo(List foo) {
//this.foo = foo; Results in compile time error.
}
}
W powyższym przypadku zdefiniowaliśmy konstruktor dla „Testu” i nadaliśmy mu metodę „setFoo”.
O konstruktora: Konstruktor może być wywołany tylko jeden raz na tworzenie obiektów za pomocą new
słowa kluczowego. Nie można wywoływać konstruktora wiele razy, ponieważ konstruktor nie jest do tego przeznaczony.
Informacje o metodzie: Metodę można wywołać dowolną liczbę razy (nawet nigdy), a kompilator o tym wie.
Scenariusz 1
private final List foo; // 1
foo
jest zmienną instancji . Kiedy tworzymy Test
obiekt klasy, wówczas zmienna instancji foo
zostanie skopiowana do obiektu Test
klasy. Jeśli przypiszemy foo
do konstruktora, to kompilator wie, że konstruktor zostanie wywołany tylko raz, więc nie ma problemu z przypisaniem go do konstruktora.
Jeśli przypiszemy foo
wewnątrz metody, kompilator wie, że metodę można wywołać wiele razy, co oznacza, że wartość będzie musiała zostać zmieniona wiele razy, co nie jest dozwolone dla final
zmiennej. Kompilator decyduje więc, że konstruktor jest dobrym wyborem! Możesz przypisać wartość do zmiennej końcowej tylko raz.
Scenariusz 2
private static final List foo = new ArrayList();
foo
jest teraz zmienną statyczną . Kiedy tworzymy instancję Test
klasy, foo
nie zostanie ona skopiowana do obiektu, ponieważ foo
jest statyczna. Teraz foo
nie jest niezależną własnością każdego obiektu. Jest to właściwość Test
klasy. Ale foo
może być widoczny dla wielu obiektów i jeśli każdy obiekt utworzony przy użyciu new
słowa kluczowego, które ostatecznie wywoła Test
konstruktor, który zmienia wartość w momencie tworzenia wielu obiektów (Pamiętaj, że static foo
nie jest kopiowany w każdym obiekcie, ale jest dzielony między wieloma obiektami .)
Scenariusz 3
t.foo.add("bar"); // Modification-2
Powyżej Modification-2
jest z twojego pytania. W powyższym przypadku nie zmieniasz pierwszego obiektu, do którego istnieje odwołanie, ale dodajesz zawartość, foo
która jest dozwolona. Kompilator narzeka jeśli spróbujesz przypisać new ArrayList()
do foo
zmiennej referencyjnej.
Reguła Jeśli zainicjowałeś final
zmienną, nie możesz jej zmienić tak, aby odwoływała się do innego obiektu. (W tym przypadku ArrayList
)
klas końcowych nie można podklasować. Metody
końcowe nie mogą zostać zastąpione. (Ta metoda jest w nadklasie) metody
końcowe mogą zostać zastąpione. (Przeczytaj to gramatycznie. Ta metoda należy do podklasy)