Одним из интересных инструментов, о которых я узнал на JavaOne 2012, является The Checker Framework . На одной из веб-страниц Checker Framework говорится, что Checker Framework «улучшает систему типов Java, делая ее более мощной и полезной,« позволяя разработчикам программного обеспечения »обнаруживать и предотвращать ошибки в своих программах Java». Один из способов взглянуть на Checker Framework — это реализация того, что могло бы произойти в JSR 305 («Аннотации для обнаружения дефектов программного обеспечения»), если бы он не попал в стадию бездействия .
Целью JSR 308 («Аннотации на типах Java») является «расширение синтаксиса аннотаций Java для разрешения аннотаций в любом случае типа». Как только JSR 308 будет утвержден и станет частью языка программирования Java, аннотации будут разрешены там, где они в настоящее время не разрешены. Хотя JSR 308 все еще находится на этапе раннего предварительного просмотра 2 , Checker Framework позволяет разработчику включать закомментированный код аннотации в местах, которые в настоящее время не разрешены, пока не станут доступны в JSR 308. Здесь важно отметить, что JSR 308 делает аннотации только в более общем виде. доступный (указывает больше типов исходного кода, к которому они могут быть применены) и не указывает никаких новых аннотаций.
Для Checker Framework требуется Java SE 6 или более поздняя версия. Среду Checker Framework можно загрузить в виде одного ZIP-файла по адресу http://types.cs.washington.edu/checker-framework/current/checkers.zip . Загруженный файл может быть разархивирован в платформу checker-framework
каталогов, а затем может быть установлена переменная среды CHECKERS
указывающая на подкаталог этого расширенного каталога ‘checkers’. Например, если CHECKERS
checkers.zip
разархивирован в C:\checker-framework
, для переменной среды CHECKERS
должно быть установлено C:\checker-framework\checkers
.
Когда Checkers Framework checkers.zip
был загружен, расширен и указан переменной среды CHECKERS
, пришло время попробовать Checker Framework. Далее показан «длинный путь» запуска Checker Framework, который используется с тегом -version
для проверки того, что Checker Framework применяется:
Windows
1
|
java -Xbootclasspath/p:%CHECKERS%/binary/jsr308-all.jar -jar %CHECKERS%/binary/jsr308-all.jar -version |
Linux
1
|
java -Xbootclasspath/p:$CHECKERS/binary/jsr308-all.jar -jar $CHECKERS/binary/jsr308-all.jar -version |
Вышеуказанное должно привести к выводу, который будет выглядеть примерно так, как показано на следующем снимке экрана.
Установленная Checker Framework теперь может быть применена для компиляции кода. В следующем листинге кода показан простой класс, который указывает, что аргумент метода не должен быть нулевым с помощью аннотации checkers.nullness.quals.NonNull ( @NonNull ).
Пример использования Checker Framework @NonNull
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
package dustin.examples; import checkers.nullness.quals.NonNull; import static java.lang.System.out; public class CheckersDemo { public void printNonNullToString( @NonNull final Object object) { out.println(object.toString()); } public static void main( final String[] arguments) { final CheckersDemo me = new CheckersDemo(); final String nullStr = null ; me.printNonNullToString(nullStr); } } |
Приведенный выше листинг кода показывает, что в метод передается значение NULL с аргументом, аннотированным @NonNull
. NetBeans 7.3 помечает это желтыми загогулинами и предупреждает, если наведен. Это показано на следующих снимках экрана.
Хотя NetBeans отмечает нулевое значение параметра, помеченного аннотацией @NonNull
, компилятор создает этот код без жалоб. Вот тут-то и появляется Checker Framework. Поскольку вводить длинную команду, которую я показывал ранее, неудобно, я либо запускаю указанную выше команду со скриптом, либо устанавливаю псевдоним, как описано в инструкциях по установке Checker Framework . В этом случае я буду использовать псевдоним:
Настройка псевдонима командной строки Windows для проверки Java
1
|
doskey javachecker=java -Xbootclasspath/p:%CHECKERS%\binary\jsr308-all.jar -jar %CHECKERS%\binary\jsr308-all.jar $* |
Настройка этого псевдонима и запуск его с флагом -version
продемонстрирован на следующем снимке экрана.
Гораздо проще применить этот подход с набором псевдонимов. Это может быть использовано для компиляции рассматриваемого класса, как показано ниже (команда, использующая мой псевдоним ‘javachecker’ и изображение, показывающее результат).
1
|
javachecker -d classes src\dustin\examples\*.java |
Приведенная выше команда демонстрирует, что я могу использовать обычные параметры javac
, такие как -d
чтобы указать каталог назначения для скомпилированных файлов .class
и передать исходные файлы Java для компиляции в обычном режиме. В этом примере также показано, что без указания процессора проверки для запуска в процессе компиляции дополнительная типизация @NotNull
не применяется во время компиляции.
Прежде чем показать, как указать процессор для принудительного применения @NonNull
во время компиляции, я хочу быстро продемонстрировать, что этот подход к компиляции все равно будет сообщать о стандартных ошибках компилятора. Как раз для этого примера я переименовал переменную ‘nullStr’, переданную интересующему методу в строке 17, в ‘nullStry’, чтобы это было ошибкой компилятора. На следующих двух снимках экрана показано это изменение (и сообщенная ошибка компиляции NetBeans) и то, как подход компиляции Checker Framework также сообщает об ошибке javac
.
Показав, что этот подход к компиляции нормально компилирует компилируемый код, нормально сообщает об ошибках компилятора и соответствующим образом показывает версию, пришло время применить его для более строгого применения типов. Я исправляю ошибку компилятора в своем коде, удаляя лишние «y», которые я добавил. Затем мне нужно передать -processor checkers.nullness.NullnessChecker
в качестве дополнительного флага и аргумента процесса компиляции. Обратите внимание, что есть и другие процессоры, кроме NullnessChecker , но я использую NullnessChecker
здесь для принудительного применения @NonNull
во время компиляции.
Ниже показана команда вместе с окном вывода, демонстрирующее эту команду в действии. Обратите внимание, что процесс компиляции не может быть завершен, и сообщается об ошибке, @NonNull
с @NonNull
типизации @NonNull
.
1
|
javachecker -processor checkers.nullness.NullnessChecker -d classes src\dustin\examples\*.java |
В этом сообщении в блоге рассказывается о Checker Framework и показано, как быстро применить его для более строгого соблюдения типов в исходном коде Java. Здесь я сосредоточился только на одном типе более строгой типизации, но Checker Framework предоставляет другие встроенные проверки типов и поддерживает возможность написания пользовательских проверок принудительного исполнения типов.
Ссылка: Checker Framework от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .