W 2005 roku, wraz z pojawieniem się języka Java 5, dowiedzieliśmy się o nowych obiektach zwanych adnotacjami.
Adnotacje to specjalna forma metadanych składniowych, które można zadeklarować w kodzie. Służą do analizy kodu podczas kompilacji lub podczas wykonywania programu. Adnotację można porównać do etykiety, znacznika lub wskazówki kompilatora.
Prawdopodobnie spotkałeś się już z adnotacjami. Na przykład, gdy nadpisujemy metodę klasy nadrzędnej, piszemy @Override przed samą metodą . Jest to adnotacja wskazująca, że metoda nadrzędna zostanie zastąpiona w klasie pochodnej.
Składnia:
@Override
public int hashCode() {
return super.hashCode();
}
Od razu chcę zauważyć, że adnotacje mają zastosowanie nie tylko do metod, ponieważ są używane w połączeniu z pakietami, klasami, metodami, polami i parametrami.
Aby zrozumieć, jak działają adnotacje, zapoznajmy się najpierw z koncepcją interfejsu znaczników. Konieczność oznaczenia klasy w określony sposób w celu wykonania na niej określonych działań istniała dla programistów Java od czasu pojawienia się tego języka.
Przed Javą 5 używali interfejsu, który nawet nie przypominał samego siebie i nie odpowiadał zamierzonemu przeznaczeniu. Było bez metod, nie zawierało żadnej umowy, tylko oznaczało klasę do izolacji.
Taki interfejs nazwano interfejsem znacznikowym. Z nazwy wynika, że jego zadaniem jest oznaczanie klas dla JVM, kompilatora, czy jakiejś biblioteki. Pozostało jeszcze kilka interfejsów znaczników, takich jak Serializable . Ten znacznik pozwala nam oznaczyć klasę komunikatem, że jej instancje mogą być serializowane.
Widzieliśmy, że korzystanie z interfejsów znaczników nadal istnieje, nawet po wprowadzeniu adnotacji.
Równoważne użycie interfejsu adnotacji i znaczników:
@MyAnnotation
public class MyClass {}
public class MyClass implements MarkerInterface {}
Pomimo tego, że zadanie obu podejść jest takie samo, istnieje wyraźna różnica w ich realizacji. Rozważmy na przykład interfejs i adnotację, aby określić, czy klasa należy do określonego typu.
W przypadku interfejsu zaznaczamy klasę: nawet jeśli zostanie użyty nieprawidłowo i wystąpi błąd, zostanie on wykryty na etapie kompilacji i program nie zostanie uruchomiony.
W przypadku adnotacji wszystko nie jest takie proste: błąd zostanie wykryty już w czasie wykonywania, co oznacza, że \u200b\u200bprogram rozpocznie wykonywanie, ale zgodnie z oczekiwaniami nie zakończy się.
Należy zauważyć, że jeśli chcemy oznaczyć klasę do przyszłego użytku, jej instancje muszą zostać przekazane do określonej metody:
public class MyInteger implements Sum {}
interface Sum {};
public static void main(String[] args) throws IOException {
increase(new MyInteger());
}
public static void increase(Sum count) {
// TODO
}
Interfejs znaczników działa tutaj najlepiej.
Adnotacje są najlepiej używane, gdy istnieje potrzeba czegoś więcej, na przykład parametrów, które adnotacja umożliwia przekazanie.
Spójrzmy na standardowe adnotacje w JDK:
adnotacja | Opis | Przykład |
---|---|---|
@Nadpisanie | Określa, że metoda zastępuje metodę klasy nadrzędnej lub implementuje metodę klasy abstrakcyjnej lub interfejsu. |
|
@Przestarzałe | Oznacza kod jako przestarzały. |
|
@Tłumić ostrzeżenia | Wyłącza ostrzeżenia kompilatora dla elementu z adnotacjami. Pamiętaj, że jeśli chcesz wyłączyć wiele kategorii ostrzeżeń, muszą one być ujęte w nawiasy klamrowe, na przykład @SuppressWarnings ({"unchecked", "cast"}) . |
W tym przykładzie próbujemy dodać do listy w metodzie, która nie ma zdefiniowanego typu (ogólnego). Kompilator ostrzeże nas o tym. Chociaż jest to bardzo przydatne, czasami jest zbyt wiele „ostrzeżeń” i są one bardzo głośne. W takim przypadku można użyć tej adnotacji metody z parametrem znacznika ostrzeżenia kompilatora. Znaczników jest bardzo dużo, więc nie trzeba wszystkiego pamiętać, zwykle IDEA podpowie, który położyć. Inny przykład użycia z przekazywanymi wieloma parametrami:
|
GO TO FULL VERSION