Разработка программ. Мои заметки.

January 17, 2017 at 19:06

NullPointerException в Java. Элегантное противостояние.

3. Попытки элегантного противостояния.

С большего, язык Java не имел и не имеет никаких готовых встроенных синтаксических “информаторов”, позволяющих внятно указать, что некоторое поле или параметр гарантированно не может принять значение null и его не нужно проверять перед использованием. Или наоборот, что поле, во время выполнения, порой содержит null и его обязательно нужно проверить перед обращением. Разумеется, можно всё это указать в комментариях к полю/параметру, но это будет скорее послание программисту, поскольку компилятор автоматически не сможет этого понять и подсказать нам, если мы сами этого не заметили.

Тем не менее, существуют возможности расширить язык таким образом, что бы компилятор обращал внимание на такие ситуации и предупреждал разработчиков. Довольно популярной идеей стало использование аннотаций.

Тут снова небольшое букварное отступление. Аннотация — это любое слово в тексте вашей программы перед которым стоит значок @. Располагаться такое слово может не везде, а как и положено умному слову, только в определённых местах кода. По своей сути, аннотация является некоей меткой, которая информирует компилятор о том, что в этом месте нужно на что-то обратить внимание, даёт какую-то дополнительную информацию компилятору о том, как обращаться с помеченным куском кода. Такого рода информацию принято называть Мета-информацией.

Аннотация никак не влияет на логику самой программы. Аннотация, это мостик от кода к компилятору, который этот код обрабатывает. Своего рода туннель между разными измерениями. Цель — сказать что-то важное, что бы компилятор во время своей работы учёл эту информацию.

Технически, аннотация — это Java класс, написанный по определённым законам. Что бы компилятор понимал что ему хочет сказать конкретная аннотация, этот класс должен быть доступен компилятору в его CLASSPATH во время компиляции исходного текста программы. Аннотации, кстати, могут работать и во время выполнения программы. Там они, опять же, не влияют на саму логику работы программы, но могут сканировать значения некоторых параметров, фиксируя, скажем, продолжительность работы нужного метода. Для этого, класс аннотации должен быть доступен программе и во время её выполнения. То есть, как правило, быть погружен в некий jar и находиться в CLASSPATH выполняемого приложения. Аннотации могут иметь параметры.

Стандартные библиотеки Java уже содержат несколько готовых к употреблению аннотаций. Они хорошо известны. Например @Override, @Deprecated. Если желаете иметь свои, то их нужно реализовать и вставить в код, согласно синтаксису языка.

Впервые, аннотации появились в Java 5 и с тех пор их, как ярлычки, можно было вешать на любых объявлениях в коде. Цеплять к объявлениям классов, методов, переменных. А начиная с Java 8 добавилась возможность аннотировать типы (Type Annotations). То есть их стало можно “приклеивать” к любому месту, где упоминается какой-то Java тип (ну любой класс, по сути). То есть в параметрах методов, в возврате методов, в принудительном преобразовании типов.

Первоначально, добавленные ещё в Java 5, аннотации выглядели вот так:


    @Author( name = "John Doe", date = "16/07/2016" )
    class MyClass()
    {
        @Override
        void someMethod() {...}
    }
    

А в Java 8 их синтаксис расширился и теперь стало возможно делать ещё и так:


    MyObject mo = new @Interned MyObject(); //  Создание объекта
    String strTmp = (@NonNull String)str;   //  Преобразование типа

    class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }
    

Напоминаю, что не все аннотации, приведённые в примерах, обязательно присутствуют в стандартных библиотеках Java. Некоторые из них вы должны реализовать сами или взять готовую библиотеку в которой они реализованы. Примеры лишь демонстрируют допустимый синтаксис употребления аннотаций в разных версиях языка.

Автор — Владимир Рыбов