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ą newsł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
foojest zmienną instancji . Kiedy tworzymy Testobiekt klasy, wówczas zmienna instancji foozostanie skopiowana do obiektu Testklasy. Jeśli przypiszemy foodo konstruktora, to kompilator wie, że konstruktor zostanie wywołany tylko raz, więc nie ma problemu z przypisaniem go do konstruktora.
Jeśli przypiszemy foowewną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 finalzmiennej. 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();
foojest teraz zmienną statyczną . Kiedy tworzymy instancję Testklasy, foonie zostanie ona skopiowana do obiektu, ponieważ foojest statyczna. Teraz foonie jest niezależną własnością każdego obiektu. Jest to właściwość Testklasy. Ale foomoże być widoczny dla wielu obiektów i jeśli każdy obiekt utworzony przy użyciu newsłowa kluczowego, które ostatecznie wywoła Testkonstruktor, który zmienia wartość w momencie tworzenia wielu obiektów (Pamiętaj, że static foonie jest kopiowany w każdym obiekcie, ale jest dzielony między wieloma obiektami .)
Scenariusz 3
t.foo.add("bar"); // Modification-2
Powyżej Modification-2jest z twojego pytania. W powyższym przypadku nie zmieniasz pierwszego obiektu, do którego istnieje odwołanie, ale dodajesz zawartość, fooktóra jest dozwolona. Kompilator narzeka jeśli spróbujesz przypisać new ArrayList()do foozmiennej referencyjnej.
Reguła Jeśli zainicjowałeś finalzmienną, 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)