W Javie 8 mogę łatwo napisać:
interface Interface1 {
default void method1() {
synchronized (this) {
// Something
}
}
static void method2() {
synchronized (Interface1.class) {
// Something
}
}
}
Otrzymam pełną semantykę synchronizacji, której mogę używać także na zajęciach. Nie mogę jednak użyć synchronized
modyfikatora do deklaracji metod:
interface Interface2 {
default synchronized void method1() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
static synchronized void method2() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
}
Teraz, można argumentować, że te dwa interfejsy zachowują się tak samo, z wyjątkiem, że Interface2
ustanawia umowę w sprawie method1()
oraz w sprawie method2()
, która jest nieco silniejsze niż to, co Interface1
robi. Oczywiście możemy również argumentować, że default
implementacje nie powinny przyjmować żadnych założeń dotyczących konkretnego stanu implementacji lub że takie słowo kluczowe po prostu nie zwiększy jego wagi.
Pytanie:
Jaki jest powód, dla którego grupa ekspertów JSR-335 postanowiła nie obsługiwać synchronized
metod interfejsu?
default synchronized
, ale niekoniecznie dla static synchronized
, chociaż zgodziłbym się, że ten drugi mógł zostać pominięty ze względów spójności.
synchronized
modyfikator może zostać zastąpiony w podklasach, dlatego miałoby to znaczenie tylko wtedy, gdyby istniało coś jako ostateczne domyślne metody. (Twoje drugie pytanie)
synchronized
w superklasach, skutecznie usuwając synchronizację. Nie zdziwiłbym się jednak, że brak wsparcia synchronized
i brak wsparcia final
jest powiązany, być może z powodu wielokrotnego dziedziczenia (np. Dziedziczenie void x()
i synchronized void x()
itp.). Ale to spekulacje. Jestem ciekawy wiarygodnego powodu, jeśli taki istnieje.
super
co wymaga pełnej ponownej implementacji i możliwego dostępu do członków prywatnych. Poza tym istnieje powód, dla którego metody te nazywane są „obrońcami” - są one obecne, aby umożliwić łatwiejsze dodawanie nowych metod.