W Javie jest całkowicie legalne definiowanie final
argumentów w metodach interfejsu i nie przestrzeganie tego w klasie implementującej, np .:
public interface Foo {
public void foo(int bar, final int baz);
}
public class FooImpl implements Foo {
@Override
public void foo(final int bar, int baz) {
...
}
}
W powyższym przykładzie, bar
i baz
ma przeciwległe final
definicji w klasie VS interfejsu.
W ten sam sposób nie final
są wymuszane żadne ograniczenia, gdy jedna metoda klasy rozszerza inną, albo abstract
nie.
Chociaż final
ma jakąś praktyczną wartość w treści metody klasy, czy jest jakiś punkt określający final
parametry metody interfejsu?
final
i tak nie robi nic z rodzimymi typami, ponieważ są one kopiowane.interface
definicje różnią się tylkofinal
atrybutem argumentu, wówczas.class
pliki wynikowe są identyczne bajt po bajcie (i oczywiściejavap -v
daje to samo wyjście). To samo dotyczy dwóch klas, którefinal
, nawiasem mówiąc, różnią się tylko atrybutem!Odpowiedzi:
Nie wydaje się, żeby to miało jakiś sens. Zgodnie ze specyfikacją języka Java 4.12.4 :
Jednak
final
modyfikator parametru metody nie jest wspomniany w regułach dopasowywania podpisów zastąpionych metod i nie ma wpływu na obiekt wywołujący, tylko w treści implementacji. Ponadto, jak zauważył Robin w komentarzu,final
modyfikator parametru metody nie ma wpływu na wygenerowany kod bajtowy. (Nie dotyczy to innych zastosowańfinal
.)źródło
final
modyfikator nie jest egzekwowany w klasie implementacyjnej. Twój podpis interfejsu może po prostu kłamać.Niektóre IDE skopiują podpis metody abstrakcyjnej / interfejsu podczas wstawiania metody implementującej do podklasy.
Nie sądzę, żeby miało to jakiekolwiek znaczenie dla kompilatora.
EDYCJA: Chociaż uważam, że tak było w przeszłości, nie sądzę, aby obecne IDE to robiły.
źródło
static transient
pól. ;)Końcowe adnotacje parametrów metody są zawsze istotne tylko dla implementacji metody, nigdy dla osoby wywołującej. Dlatego nie ma rzeczywistego powodu, aby używać ich w podpisach metod interfejsu. Chyba że chcesz stosować ten sam spójny standard kodowania, który wymaga ostatecznych parametrów metody, we wszystkich sygnaturach metod. Miło jest móc to zrobić.
źródło
Aktualizacja: Oryginalna odpowiedź poniżej została napisana bez pełnego zrozumienia pytania, dlatego też nie odnosi się bezpośrednio do pytania.
:)
Niemniej jednak musi być pouczająca dla osób, które chcą zrozumieć ogólne użyciefinal
słowa kluczowego.Jeśli chodzi o pytanie, chciałbym zacytować swój komentarz od dołu.
Mogę wymyślić dwa powody, dla których podpis metody może mieć
final
parametry: Beans i Objects (w rzeczywistości oba są z tego samego powodu, ale nieco inne konteksty ).Obiekty:
final
Kluczowe zapewnić, że nie będzie przypadkowo utworzyć nową lokalną garnek do gotowania, pokazując błąd kompilacji, gdy staraliśmy się zrobić. Dzięki temu bulion z kurczaka został dodany do naszego oryginalnego garnka do gotowania, któryaddChicken
otrzymaliśmy według metody. Porównaj to zaddVegetables
miejscem, w którym straciliśmy kalafior, ponieważ dodało to do nowego lokalnego garnka do gotowania zamiast oryginalnego garnka, który dostał.Fasola: Jest to ta sama koncepcja co obiekty (jak pokazano powyżej) . Ziarna są zasadniczo
Object
w Javie. Jednak fasole (JavaBeans) są używane w różnych aplikacjach jako wygodny sposób przechowywania i przekazywania określonej kolekcji powiązanych danych. Podobnie jakaddVegetables
może to zepsuć proces gotowania, tworząc nowy garnek do gotowaniaStringBuilder
i wyrzucając go z kalafiorem, tak samo może zrobić to samo z garnkiem JavaBean .źródło
final
w interfejsie, ale nie jest to ostateczne wdrożenie. Byłoby bardziej sensowne, gdyby którekolwiek (a)final
słowo kluczowe nie było dozwolone dla argumentów metody interfejsu (abstrakcyjne) (ale można go użyć w implementacji), lub (b) zadeklarowanie argumentu, ponieważfinal
w interfejsie zmusiłoby go do zadeklarowaniafinal
w implementacji (ale nie zmuszony do niefinałów).:)
Uważam, że może to być zbyteczny szczegół, ponieważ to, czy jest ostateczny, czy nie, jest szczegółem implementacji.
(Coś w rodzaju deklarowania metod / członków w interfejsie jako publicznych).
źródło