Próbuję tylko zrozumieć, dlaczego wszystkie pola zdefiniowane w interfejsie są niejawnie static
i final
. Pomysł utrzymywania pól static
ma dla mnie sens, ponieważ nie możesz mieć obiektów interfejsu, ale dlaczego one są final
(domyślnie)?
Czy ktoś wie, dlaczego projektanci Java zdecydowali się na tworzenie pól w interfejsie static
i final
?
Odpowiedzi:
Interfejs nie może mieć zachowania ani stanu, ponieważ ma określać tylko kontrakt interakcji, bez szczegółów implementacji. Brak zachowania jest wymuszany przez niedopuszczenie do treści metod / konstruktorów lub bloków inicjujących statyczne / instancje. „Brak stanu” jest wymuszane przez zezwolenie tylko na statyczne pola końcowe. Dlatego klasa może mieć stan (stan statyczny), ale stan instancji nie jest wywnioskowany przez interfejs.
BTW: Stała w Javie jest definiowana przez statyczne pole końcowe (i zgodnie z konwencją nazwa używa UPPER_CASE_AND_UNDERSCORES).
źródło
static final
, które są tak bliskie rzeczywistemu (rzeczywistemu C / C ++),const
jak można uzyskać w Javie. Niestety jest to dorozumiane i może prowadzić do nieporozumień dla osób niebędących ekspertami. (Właśnie zdałem sobie sprawę, że tak jest,static
ponieważ zauważyłem niezamierzone zachowanie. Dowiedziałem się, że pochodzą onefinal
tylko z tej odpowiedzi.)Powód istnienia
final
Dowolne implementacje mogą zmieniać wartość pól, jeśli nie są zdefiniowane jako ostateczne. Wtedy staną się częścią realizacji. Interfejs to czysta specyfikacja bez żadnej implementacji.
Powód istnienia
static
Jeśli są statyczne, to należą do interfejsu, a nie do obiektu ani do typu obiektu w czasie wykonywania.
źródło
W tym miejscu znajduje się kilka punktów:
Tylko dlatego, że pola w interfejsie są niejawnie statyczne final, nie oznacza, że muszą być stałymi czasu kompilacji, a nawet niezmiennymi. Możesz zdefiniować np
(Pamiętaj, że zrobienie tego wewnątrz definicji adnotacji może zmylić javac , w związku z faktem, że powyższe faktycznie kompiluje się do statycznego inicjatora).
Ponadto powód tego ograniczenia jest bardziej stylistyczny niż techniczny i wiele osób chciałoby, aby było ono zrelaksowane .
źródło
Pola muszą być statyczne, ponieważ nie mogą być abstrakcyjne (podobnie jak metody). Ponieważ nie mogą być abstrakcyjne, osoby wdrażające nie będą w stanie logicznie zapewnić różnych implementacji pól.
Myślę, że pola muszą być ostateczne, ponieważ pola mogą być dostępne dla wielu różnych implementatorów, co pozwala na ich zmianę, może być problematyczne (ponieważ synchronizacja). Również, aby uniknąć ponownego wdrożenia (ukrycia).
Tylko moja myśl.
źródło
public static
pole, którego nie mafinal
, findbugs będzie narzekać (słusznie!).Uważam, że wymóg, aby pola były ostateczne, był zbyt restrykcyjny i błędem projektantów języka Java. Zdarzają się sytuacje, gdy np. Przy obsłudze drzewa trzeba ustawić w implementacji stałe, które są wymagane do wykonywania operacji na obiekcie typu interfejs. Wybór ścieżki kodu w klasie implementującej jest kludge. Obejście, którego używam, to zdefiniowanie funkcji interfejsu i zaimplementowanie jej, zwracając literał:
Jednak użycie tej składni byłoby prostsze, jaśniejsze i mniej podatne na nieprawidłową implementację:
źródło
Specyfikacja, kontrakty ... Instrukcja maszynowa dla dostępu do pola używa adresu obiektu plus przesunięcie pola. Ponieważ klasy mogą implementować wiele interfejsów, nie ma możliwości, aby pole interfejsu innego niż końcowe miało takie samo przesunięcie we wszystkich klasach rozszerzających ten interfejs. Dlatego też musi być zaimplementowany inny mechanizm dostępu do pola: dwa dostępy do pamięci (pobranie offsetu pola, pobranie wartości pola) zamiast jednego plus utrzymanie rodzaju wirtualnej tablicy pól (odpowiednik wirtualnej tabeli metod). Chyba po prostu nie chcieli komplikować jvm pod kątem funkcjonalności, którą można łatwo zasymulować za pomocą istniejących rzeczy (metod).
W scali możemy mieć pola w interfejsach, chociaż wewnętrznie są one zaimplementowane tak, jak wyjaśniłem powyżej (jako metody).
źródło
static
:Wszystko (zmienna lub metoda), która jest
static
w Javie, może być wywołane jakoClassname.variablename
lubClassname.methodname
lub bezpośrednio. Nie jest obowiązkowe wywoływanie go tylko przy użyciu nazwy obiektu.W interfejsie obiekty nie mogą być deklarowane i
static
umożliwia wywoływanie zmiennych tylko poprzez nazwę klasy bez konieczności podawania nazwy obiektu.final
:Pomaga utrzymać stałą wartość zmiennej, ponieważ nie można jej przesłonić w jej podklasach.
źródło