Dlaczego nie można rozszerzyć adnotacji w Javie?

Nie rozumiem, dlaczego nie ma dziedziczenia w adnotacjach Javy, tak jak Klasy Javy. Myślę, że byłoby to bardzo przydatne.

Na przykład: Chcę wiedzieć, czy dana adnotacja jest walidatorem. Dzięki dziedziczeniu mogłem odruchowo poruszać się po superklasach, aby wiedzieć, czy ta adnotacja rozszerza ValidatorAnnotation. W przeciwnym razie, Jak mogę to osiągnąć?

Czy ktoś może podać powód tej decyzji projektowej?
Author: Andrew Brēza, 2009-10-26

8 answers

O tym, dlaczego nie został zaprojektowany w ten sposób, możesz znaleźć odpowiedź w JSR 175 Design FAQ, gdzie jest napisane:

Dlaczego nie wspierasz podtypowania adnotacji (gdzie jeden typ adnotacji rozszerza inny)?

Komplikuje Typ adnotacji system, i sprawia, że znacznie więcej trudno napisać "konkretne narzędzia".

"Specific Tools" - programy, które odpytują znane typy adnotacji arbitralnych programy zewnętrzne. Stub Generatory, na przykład, należą do tej kategorii. Programy te będą czytać adnotacje klasy bez wczytywania ich do maszyny wirtualnej, ale będzie ładować interfejsy adnotacji.

Więc, tak myślę, powodem jest to, że po prostu pocałunek. W każdym razie wydaje się, że ten problem (wraz z wieloma innymi) jest rozpatrywany jako część JSR 308, a nawet można znaleźć alternatywny kompilator z tą funkcjonalnością już opracowany przez Mathias Ricken .

 152
Author: pedromarce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-21 20:52:03

Rozszerzalne adnotacje skutecznie dodałyby ciężar określania i utrzymywania innego systemu typów. I byłby to dość unikalny system typów, więc nie można po prostu zastosować paradygmatu typu OO.

Przemyśl wszystkie problemy związane z wprowadzaniem polimorfizmu i dziedziczenia do adnotacji (np. co się dzieje, gdy subadnotacja zmienia parametry metadnotacji, takie jak retencja?)

I cała ta dodatkowa złożoność dla jakiego przypadku użycia?

Chcesz wiedzieć czy dana adnotacja należy do kategorii?

Spróbuj tego:

@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
    String category();
}

@Category(category="validator")
public @interface MyFooBarValidator {

}

Jak widać, można łatwo grupować i kategoryzować adnotacje bez nadmiernego bólu za pomocą dostarczonych udogodnień.

Więc, KISS jest powodem, dla którego nie wprowadzamy systemu typów meta-type do języka Java.

[P. S. edit]

Użyłem tego ciągu po prostu do demonstracji i w związku z otwartą meta adnotacją. Dla własnego projektu, oczywiście można użyć enum of typy kategorii i określenie wielu kategorii ("wielokrotne dziedziczenie") do danej adnotacji. Należy pamiętać, że wartości są całkowicie fałszywe i tylko do celów demonstracyjnych:

@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
    AnnotationCategory[] category();
}
public enum AnnotationCategory {
    GENERAL,
    SEMANTICS,
    VALIDATION,
    ETC
}

@Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
public @interface FooBarAnnotation {

}

 65
Author: alphazero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-28 17:49:54

W pewnym sensie już go masz z adnotacjami - Meta adnotacje. Jeśli dodajesz adnotację za pomocą metadanych, jest to na wiele sposobów równoważne rozszerzeniu dodatkowego interfejsu. Adnotacje są interfejsami, więc polimorfizm tak naprawdę nie wchodzi w grę, a ponieważ mają charakter statyczny, nie może być dynamicznego wysyłania w czasie wykonywania.

W twoim przykładzie walidatora, możesz po prostu na adnotacji uzyskać Typ adnotacji i sprawdzić, czy ma walidator meta-adnotacja.

Jedyny przypadek użycia, jaki widziałem, że dziedziczenie pomogłoby, to gdybyś chciał mieć możliwość uzyskania adnotacji za pomocą super type, ale dodałoby to całą złożoność, ponieważ dana metoda lub Typ mogą mieć dwie takie adnotacje na sobie, co oznacza, że tablica musiałaby być zwrócona zamiast tylko jednego obiektu.

Myślę więc, że ostateczną odpowiedzią jest to, że przypadki użycia są ezoteryczne i komplikują bardziej standardowe przypadki użycia, co nie jest tego warte.

 11
Author: Yishai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-28 17:59:46

Projektanci Java adnotation support wprowadzili szereg "uproszczeń" ze szkodą dla społeczności Java.

  1. Brak podtypów adnotacji czyni wiele złożonych adnotacji niepotrzebnie brzydkimi. Nie można po prostu mieć atrybutu w adnotacji, który może pomieścić jedną z trzech rzeczy. Trzeba mieć trzy oddzielne atrybuty, co myli programistów i wymaga walidacji runtime, aby upewnić się, że tylko jeden z trzech jest używany.

  2. Tylko jeden adnotacja danego typu na stronę. Doprowadziło to do zupełnie niepotrzebnego wzorca adnotacji kolekcji. @ Validation i @Validations, @ Image I @Images itp.

Drugi jest naprawiany w Javie 8, ale jest już za późno. Wiele frameworków zostało napisanych w oparciu o to, co było możliwe w Javie 5, a teraz te brodawki API zostaną na długo.

 5
Author: Konstantin Komissarchik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-20 16:31:42

Nigdy o tym nie myślałem, ale... wygląda na to, że masz rację, nie ma problemu z dziedziczeniem adnotacji (przynajmniej nie widzę z tym problemu).

O twoim przykładzie z 'validator' adnotacja - możesz wtedy wykorzystać 'meta-adnotacja'. Np. do całego interfejsu adnotacji stosuje się określoną meta-adnotację.

 2
Author: denis.zhdanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-26 13:57:42

Ten sam problem mam. Nie, Nie możesz. sam "zdyscyplinowałem" pisanie właściwości w adnotacjach, aby respektować niektóre standardy, więc na zewnątrz, gdy dostajesz adnotację, możesz "powąchać", jaki to rodzaj adnotacji przez właściwości, które posiada.

 1
Author: ante.sabo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-26 10:41:08

Jedna rzecz, którą mógłbym wymyślić, to możliwość posiadania wielu adnotacji. Możesz więc dodać walidator i bardziej konkretną adnotację w tym samym miejscu. Ale mogę się mylić:)

 1
Author: Janusz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-26 10:51:49

Mogę być trzy lata spóźniony w odpowiedzi na to pytanie, ale uważam, że to interesujące, ponieważ znalazłem się w tym samym miejscu. Oto moje zdanie na ten temat. Adnotacje można wyświetlać jako liczby. Dostarczają one informacji jednokierunkowej - wykorzystują je lub tracą.

Miałem sytuację, w której chciałem symulować GET, POST, PUT i DELETE w aplikacji internetowej. Tak bardzo chciałem mieć" super "adnotację o nazwie "HTTP_METHOD". Później przyszło mi do głowy, że to nie ma znaczenia. Musiałem. rozlicz się z użyciem ukrytego pola w formularzu HTML, aby zidentyfikować DELETE I PUT (ponieważ POST I GET były i tak dostępne).

Po stronie serwera wypatrzyłem ukrytego parametru żądania o nazwie "_method". Jeżeli wartość została wprowadzona lub usunięta, wtedy nadpisuje skojarzoną metodę żądania HTTP. Powiedziawszy to, nie miało znaczenia, czy musiałem rozszerzyć adnotację, aby wykonać pracę. Wszystkie adnotacje wyglądały tak samo, ale na serwerze były inaczej traktowane bok.

Więc w Twoim przypadku, upuść swędzenie, aby rozszerzyć adnotacje. Traktuj je jako "markery". "Reprezentują" pewne informacje, a niekoniecznie "manipulują" niektórymi informacjami.

 1
Author: mainas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 13:06:23