Разработайте программу список дел который управляется командами в консоли java
В этой статье я расскажу о том, как однажды я написал небольшую консольную программку для ведения списка задач почти полностью в функциональном стиле (за исключением использования переменных и некоторых приемов из ООП).
К сожалению, в статье помимо полезных практических приемов будут и некоторые отрицательные примеры, в частности, некоторое дублирование кода и нерациональное использование функций стандартной библиотеки.
Идея написать подобное приложение пришла мне в голову после прочтения замечательной книги Мирана Липовача «Изучай Haskell во имя добра!», которую я начал читать просто ради интереса и познания дао функционального программирования. В этом нескучном учебнике приводился исходный код программы для ведения списка задач (далее для краткости, я буду именовать список задач словом todo) на Haskell и предлагалось в качестве упражнения написать несколько функций, неописанных автором. Что сказать, мне бросили вызов.
Суть программы предельно проста. Есть обычный текстовый файл (расширение — *.txt, хотя это и не принципиально) и в нем хранится набор записей, разделенных новой строкой. Программа имеет ряд команд add, remove, view, bump с помощью которых пользователь может добавлять, удалять, просматривать и поднимать на вершину списка записи из файла. При этом все команды отдаются исключительно из командной строки.
Cинтаксис команд очень прост:
На Haskell программа, которая реализует все эти команды, с учетом возможного некорректного ввода и с рядом некоторых моих правок выглядит примерно так (не спрашивайте меня, когда и как я учил язык):
89 строк почти чистого функционального кода, и при этом, я уверен, что это еще можно оптимизировать и улучшить! Haskell дает очень ценный урок: многие программы могут быть написаны без использования циклов, переменных и некоторых других вещей, при этом программный код становится более качественным и более простым в сопровождении и тестировании.
Именно по этой причине, я рекомендую читателю познакомится с этим языком программирования, чтобы понять концепции функционального программирования и научиться функциональному мышлению.
Однако, вернемся в D.
Для интереса, я изменил некоторые команды в приложении (ну и кое-что добавил) и сделал цветной вывод на экран. Команду bump я заменил на команду head, а также ввел команду tail, которая по синтаксису совпадает с bump, но совершенно противоположна по результату действия (tail переносит задачу в самый низ списка задач).
Для работы над программой нам потребуется скачанные библиотеки QtE5 и arsd, а именно, файлы asc1251.d (из QtE5) и terminal.d (из arsd): asc1251 содержит набор процедур, которые умеют работать с кодировкой в командной строке Windows, а terminal.d — содержит набор процедур, для работы с командной строкой.
Все сказанное описывается так:
Что тут происходит? Аргумент arguments процедуры main содержит в себе список всех строк переданных в командной строке приложению плюс имя самого приложения, поэтому с помощью алгоритма drop мы избавляемся от нулевого элемента массива arguments (drop возвращает диапазон, который получается путем пропуска n первых элементов переданного в нее диапазона). Далее создаем структуру, через которую будем манипулировать терминалом и помещаем ее в переменную terminal.
Если, список аргументов после drop оказался не пустым, то в переменную command с помощью метода front выделяем первый элемент обработанного списка, а в commandArguments — с помощью drop помещаем аргументы команды манипуляции todo. Далее с помощью алгоритма array мы переводим диапазон в массив, который наряду с другими аргументами (структура терминала и сама команда) передается в исполнитель executeCommand.
Исполнитель выглядит достаточно просто:
Довольно простой код, который позволяет выбрать нужную функцию для исполнения, а также позволяет правильно обработать ситуации, когда команда манипуляции todo представляет собой пустую строку или неизвестную команду. При этом, перед попаданием в исполнитель строка приводится к нижнему регистру (toLower) и из нее вырезаются конечные и начальные пробелы (strip).
Теперь остается реализовать отдельные функции, которые будут выполнять все действия команд манипуляции списком задач.
Функция addTodo выглядит следующим образом:
Сначала из arguments удаляется первый элемент (drop), после чего выделяются только непустые строки (с помощью алгоритма filter и анонимной функции a => (a != «») ? true : false, которая описывает условие фильтрации), производится перевод в кодировку консоли (toCON из asc1251.d) и соответственно запись результата в файл (с помощью алгоритма each и анонимной функции a => file.writeln(a)).
Функция removeTodo выглядит так и имеет несколько параллелей с уже рассматривавшейся addTodo:
Если все переданные аргументы корректны, то для осуществления удаления записи из файла необходимо считать весь файл в массив строк, удалить из этого массива элемент с нужным индексом (removeNth), перенести массив строк во временный файл (each и writeln), удалить исходный файл (remove) и переименовать временный файл, используя имя исходного файла (rename). Именно это и происходит внутри блока обработки исключения, в котором для удаления элемента из массива используется вспомогательная функция removeNth, которая описывается следующим образом:
Функции moveTodoUp и moveTodoDown, с учетом рассмотренных фрагментов, реализуются достаточно просто и также используют массив-накопитель и временный файл:
Теперь можно рассмотреть одну из самых интересных функций программы todo — viewTodo. Работает она с использованием весьма простого алгоритма: в случае успешного прохождения всех предварительных проверок (количество аргументов, существование файла и т.д.) происходит считывание всего файла в массив строк, который затем нумеруется, начиная с нуля (при помощи алгоритма enumerate), а затем выводится в командную строку с помощью алгоритма each:
Естественно, перед выводом в командную строку производится окрашивание строк в голубой цвет (при этом, сам файл будет выведен в формате » номер_записи — запись»), а затем зеленым цветом будет выведена надпись «You have %d todo(s) now in file %s.» (В файле %s находится %d заметок).
Копируем все функции в один файл (не забываем про main) и компилируем командой:
Функциональный стиль позволяет гораздо проще и аккуратнее выразить алгоритм программы, делая его достаточно изящным и изысканным. Применение точечной нотации (ступенчатая обработка и использование UFCS в D) представляет собой довольно мощное средство, которое в равной степени может как улучшить читаемость кода, так и ухудшить ее, при этом чистое использование функционального подхода в D может быть несколько непрактичным, что легко исправляется совмещением его с традиционным императивным подходом.
Конечно, на одной конкретной ситуации не покажешь всех нюансов функционального программирования в D, поэтому я советую читателям внимательнее познакомится со стандартной библиотекой D (в частности, разделы std.algorithm, std.functional, std.range) и немного попрактиковаться в каком-нибудь чисто функциональном языке (Haskell, Scheme, Clojure и т.д).
P.S: Автор статьи от всего сердца благодарит создателей языка Haskell, Мирана Липовача, Мохова Геннадия Владимировича за прекрасную библиотеку QtE5 и Адама Руппа за превосходную коллекцию готовых программных решений arsd.
Сейчас уже никто не создает программы в консоли. Используя любимую IDE, разработчик чувствует себя неуютно за чужим компьютером, где её нет.
Решив разобраться в работе Ant и Maven, я поймал себя на том, что не смогу собрать приложение без них в консоли.
В данной статье я постарался уместить все этапы проектирования демонстрационного приложения, чтобы не искать справку по каждой команде на просторах Интернета.
От простого к .
Каждая программа обычно содержится в отдельном каталоге. Я придерживаюсь правила создавать в этом каталоге по крайней мере две папки: src и bin. В первой содержатся исходные коды, во второй — результат компиляции. В данных папках будет структура каталогов, зависящая от пакетов.
Один файл
Можно сделать и без лишних папок.
Берем сам файл HelloWorld.java.
Переходим в каталог, где лежит данный файл, и выполняем команды.
В данной папке появится файл HelloWorld.class. Значит программа скомпилирована. Чтобы запустить
Отделяем бинарные файлы от исходников
Теперь сделаем тоже самое, но с каталогами. Создадим каталог HelloWorld и в нем две папки src и bin.
Компилируем
Здесь мы указали, что бинарные файлы будут сохраняться в отдельную папку bin и не путаться с исходниками.
Используем пакеты
А то, вдруг, программа перестанет быть просто HelloWorld-ом. Пакетам лучше давать понятное и уникальное имя. Это позволит добавить данную программу в другой проект без конфликта имен. Прочитав некоторые статьи, можно подумать, что для имени пакета обязательно нужен домен. Это не так. Домены — это удобный способ добиться уникальности. Если своего домена нет, воспользуйтесь аккаунтом на сайте (например, ru.habrahabr.mylogin). Он будет уникальным. Учтите, что имена пакетов должны быть в нижнем регистре. И избегайте использования спецсимволов. Проблемы возникают из-за разных платформ и файловых систем.
Поместим наш класс в пакет с именем com.qwertovsky.helloworld. Для этого добавим в начало файла строчку
В каталоге src создадим дополнительные каталоги, чтобы путь к файлу выглядел так: src/com/qwertovsky/helloworld/HelloWorld.java.
Компилируем
В каталоге bin автоматически создастся структура каталогов как и в src.
Если в программе несколько файлов
HelloWorld.java
Adder.java
Ошибка возникла из-за того, что для компиляции нужны файлы с исходными кодами классов, которые используются (класс Calculator). Надо указать компилятору каталог с файлами с помощью ключа -sourcepath.
Компилируем
Если удивляет результат
Есть возможность запустить отладчик. Для этого существует jdb.
Сначала компилируем с ключом -g, чтобы у отладчика была информация.
Отладчик запускает свой внутренний терминал для ввода команд. Справку по последним можно вывести с помощью команды help.
Указываем точку прерывания на 9 строке в классе Calculator
Запускаем на выполнение.
Чтобы соориентироваться можно вывести кусок исходного кода, где в данный момент находится курссор.
Узнаем, что из себя представляет переменная а.
Выполним код в текущей строке и увидим, что sum стала равняться 2.
Поднимемся из класса Adder в вызвавший его класс Calculator.
Удаляем точку прерывания
Можно избежать захода в методы, используя команду next.
Проверяем значение выражения и завершаем выполнение.
Хорошо бы протестировать
Запускаем. В качестве разделителя нескольких путей в classpath в Windows используется ';', в Linux — ':'. В консоли Cygwin не работают оба разделителя. Возможно, должен работать ';', но он воспринимается как разделитель команд.
Создадим библиотеку
Класс Calculator оказался полезным и может быть использован во многих проектах. Перенесем всё, что касается класса Calculator в отдельный проект.
Измените также назавания пакетов в исходных текстах. В HelloWorld.java нужно будет добавить строку
Делаем архив jar
С помощью ключа -C мы запустили программу в каталоге bin.
Надо узнать, что у библиотеки внутри
Можно распаковать архив zip-распаковщиком и посмотреть, какие классы есть в библиотеке.
Информацию о любом классе можно получить с помощью дизассемблера javap.
Из результата видно, что класс содержит кроме пустого конструктора, ещё один метод sum, внутри которого в цикле вызывается метод add класса Adder. По завершении метода sum, вызывается Adder.getSum().
Без ключа -c программа выдаст только список переменных и методов (если использовать -private, то всех).
Лучше снабдить библиотеку документацией
Изменим для этого класс калькулятора.
Документацию можно создать следующей командой. При ошибке программа выдаст список возможных опций.
В результате получиться следующее
Можно подписать jar-архив
Если требуется подписать свою библиотеку цифровой подписью, на помощь придут keytool и jarsigner.
Генерируем подпись.
Генерируем Certificate Signing Request (CSR)
Содержимое полученного файла отправляем в центр сертификации. От центра сертификации получаем сертификат. Сохраняем его в файле (например, qwertokey.cer) и импортируем в хранилище
Файл qwertokey.cer отправляем всем, кто хочет проверить архив. Проверяется он так
Использование библиотеки
Есть программа HelloWorld, которая использует библиотечный класс Calculator. Чтобы скомпилировать и запустить программу, нужно присоединить библиотеку.
Компилируем
Собираем программу
Это можно сделать по-разному.
Первый способ
Здесь есть тонкости.
В строке
не должно быть пробелов в конце.
Вторая тонкость описана в [3]: в этой же строке должен стоять перенос на следующую строку. Это если манифест помещается в архив сторонним архиватором.
Программа jar не включит в манифест последнюю строку из манифеста, если в конце не стоит перенос строки.
Ещё момент: в манифесте не должно быть пустых строк между строками. Будет выдана ошибка «java.io.IOException: invalid manifest format».
При использовании команды echo надо следить только за пробелом в конце строки с main-class.
Второй способ
В данном способе избегаем ошибки с пробелом в main-class.
Третий способ
Включили код нужной библиотеки в исполняемый файл.
Запуск исполняемого jar-файла
Файл calculator.jar исполняемым не является. А вот helloworld.jar можно запустить.
Если архив был создан первыми двумя способами, то рядом с ним в одном каталоге должна находится папка lib с файлом calculator.jar. Такие ограничения из-за того, что в манифесте в class-path указан путь относительно исполняемого файла.
При использовании третьего способа нужные библиотеки включаются в исполняемый файл. Держать рядом нужные библиотеки не требуется. Запускается аналогично.
Как быть с приложениями JavaEE
Аналогично. Только библиотеки для компиляции нужно брать у сервера приложений, который используется. Если я использую JBoss, то для компиляции сервлета мне нужно будет выполнить примерно следующее
Структура архива JavaEE-приложения должна соответствовать определенному формату. Например
Способы запуска приложения на самом сервере с помощью командной строки для каждого сервера различны.
Надеюсь, данная статья станет для кого-нибудь шпаргалкой для работы с Java в командной строке. Данные навыки помогут понять содержание и смысл Ant-скриптов и ответить на собеседовании на более каверзные вопросы, чем «Какая IDE Вам больше нравится?».
В книге "97 вещей, которые должен знать каждый Java-программист" есть глава о некоторых инструментах командной строки в JDK (я дал 2 из 97 советов).
Поскольку я сам часто использую такие помощники, я хотел кратко представить их в сегодняшней статье.
Я предпочитаю командную строку для своей повседневной работы, используя комбинацию команд git , sed , grep , и т. д., bash что упрощает выполнение повторяющихся задач.
Уже в «Прагматическом программисте» была четкая ссылка на это в разделе 21:
Используйте возможности командных оболочек+
Используйте оболочку, когда графические пользовательские интерфейсы не подходят.
Также хотелось бы сослаться на книгу NealFord "Productive Programmer":
Вам не нужно бояться командной строки, это как любой язык программирования. Вы выполняете команды или сценарии и можете комбинировать их ввод и вывод в более сложные процессы. В Linux и OSX вас хорошо обслуживают встроенные bash или zsh, в Windows вы можете воспользоваться либо cmd , либо с недавних пор с подсистемой Windows для Linux (WSL).
Большинство инструментов поставляются со встроенной справкой, отображаемой по параметру -h или предоставляют страницы справки с помощью `man`. Эти справочные страницы также можно найти на веб-сайте Oracle.
Управление установками JDK с помощью SDKman
Как упоминалось в предыдущих статьях, для меня sdkman — это гений управления установками Java, Groovy, Maven, Gradle, Micronaut и многих других инструментов, а также для активации различных версий.
Для этого вы устанавливаете sdkman, например, с помощью:
curl -s "https://get.sdkman.io" | bash .
После этого по команде sdk list отображаются устанавливаемые инструменты, и с помощью команды sdk list java вы можете увидеть доступные и установленные версии JDK.
У вас есть широкий выбор версий JDK от OpenJDK до Azul Zuulu, GraalVM до Amazon и SAP JDK.
С помощью, например sdk install java 17-open , вы можете установить новые версии (вплоть до последней EAP), а с помощью sdk use java 17-open вы можете переключиться на текущую оболочку или глобально.
Простые помощники
В каждом пакете JRE и JDK помимо компилятора javac и среды выполнения java есть много полезных помощников в каталоге bin дистрибутива. Некоторые из них, как jarsigner или keytool очень специфичные, и я не буду углубляться в них здесь.
Мы начнем с некоторых полезных инструментов, а затем посвятим более сложным инструментам отдельные разделы.
Если вы хотите избавиться от зависшего процесса Java, вы можете либо найти его в диспетчере задач и закрыть его там, либо найти PID (идентификатор процесса) с помощью, ps auxww | grep java , а затем завершить его с помощью `kill`.
Вместо этого встроенный jps может предоставить тот же сервис.
Есть дополнительные параметры: -l - для полного доменного имени основного класса или пути к JAR-файлу запуска, -v - для аргументов JVM и -m - для аргументов командной строки метода main .
jstack
Чтобы получить дамп потока JVM, особенно если он завис в какой-то точке, которую вы хотите изучить более внимательно, есть 2 способа.
Либо `kill -3` производит вывод непосредственно из процесса, либо предпочтительнее с помощью `jstack`.
Статус потоков различается между kill -3 и jstack .
kill -3
jstack
jinfo
С помощью jinfo вы можете быстро получить доступ к системным свойствам, флагам JVM и аргументам JVM процесса Java.
jinfo дает полный обзор, который может помочь в обнаружении странных эффектов. Используя jinfo -flag name=value или -flag [+|-]name вы можете изменить динамические флаги JVM.
jshell
Представленная в Java 9, jshell - это была первая официальная консоль REPL (read eval print loop) для интерактивного выполнения кода Java.
Можно не только вычислять выражения и назначать переменные, но также можно создавать и динамически переопределять классы с методами.
Можно передать пути к классам в jshell, содержимое которого затем будет доступно для импорта и использования.
jshell имеет множество параметров командной строки, а также встроенные команды, которые объясняются с помощью параметра /? .
Особенно полезны /help , /save , /history и команды /vars , /types , /methods , /imports .
Для редактирования больших фрагментов кода вы можете использовать '/edit', создав свой собственный редактор, используя переменные окружения 'JSHELLEDITOR', 'VISUAL', 'EDITOR' или установить редактор указав '/path/to/editor'.
Важные пакеты java.util.(*,streams,concurrent) , такие как java.math и некоторые другие, уже импортированы по умолчанию.
Выражения присваиваются заполнителям $5 , которые можно использовать позже.
Для улучшения читабельности кода лучше использовать var начиная с Java 11, тогда переменные можно создавать без объявления типа.
Новые языковые функции, которые все еще доступны в режиме предварительного просмотра, могут быть включены с помощью параметра --enable-preview .
Очень удобной функцией jshell является автодополнение. Каждое имя класса, метода и переменной можно контекстно завершить, нажав несколько раз клавишу Tab.
Вот пример запуска игры «Жизнь» (Покойся с миром — Джон Конвей) в jshell .
Для работы с jar-файлами (Java ARchive) есть одноименная команда.
Синтаксис командной строки аналогичен команде tar .
Хотя tar по умолчанию только хранит файлы в архиве, jar также сжимает их, что приводит к значительному уменьшению размера.
Вот несколько полезных сценариев использования:
jar tf file.jar - отображать содержимое архива
jar xvf file.jar - распаковать файл архива в текущем каталоге (с отображением по v )
jar uvf file.jar -C path test.txt - добавить файл из указанной директории
Поскольку в Java 9 jar также может создавать мультирелизные архивы, совместимые с несколькими JDK и могут содержать оптимизированные файлы классов для соответствующей версии Java.
Команда Java запускает виртуальную машину Java с заданным путем к классам (каталоги, файлы и URL-адреса jar и классов) и основным классом, main метод которого выполняется.
С помощью команды java -jar file.jar main класс определяется с помощью метаинформации файла jar.
Начиная с Java 11, доступен JEP 330 (Запуск программ с однофайловым исходным кодом), поэтому исходные файлы можно запускать напрямую.
JVM можно контролировать с помощью сотен флагов, от выделения памяти с помощью флагов -Xmx и -Xms до выбора сборщика мусора с помощью флага -XG1GC и настроек журнала.
Коллекция ресурсов по флагам JVM была опубликована Betsy Rhodes на Foojay
Далее следуют несколько полезных флагов, список представляет лишь часть опций JVM.
Xshareclasses - Обмен данными класса
verbose:gc - Ведение журнала GC
Javac
Компилятор javac транслирует исходный код Java в один или несколько файлов классов, содержащих байт-код классов, выполняет начальную оптимизацию и запускает обработку аннотаций «процессорами аннотаций».
Чтобы указать все классы, от которых зависит текущий код, они или их архивы должны быть перечислены в пути к классам или пути к модулю.
Для более глубокого изучения javac потребуется отдельная статья, поэтому мы остановимся на ее почетном упоминании.
JavaP
Всякий раз, когда вы хотите изучить результат javac , javap вступает в игру.
Этот инструмент позволяет отображать сигнатуру класса, его расположение в памяти с помощью флагов -l -v -constants или инструкциями байт-кода языка стека JVM с помощью флага -c .
Это может быть полезно, если вы хотите увидеть влияние определенных опций компилятора или версий Java, или если изменилось поведение оптимизаций (размер встроенного кода).
В качестве параметра он получает полное имя класса, имя файла или URL-адрес jar.
Вот пример нашего класса Hello.java , где вы можете видеть, например, что Java 14 теперь использует операцию «invokedynamic» для конкатенации строк.
Было полезно создавать heapdumps или гистограммы (ссылочных) объектов jmap .
В настоящее время рекомендуется использовать jcmd .
jmap -clstats выводит статистику загрузчика классов
jmap -histo или jmap -histo:live выводит гистограмму
jmap -dump:live,format=b,file=heap.hprof генерирует дамп кучи.
Используя jcmd можно управлять Java процессами удаленно, существует довольно много действий, которые можно инициировать в JVM.
jcmd может использоваться интерактивно или с помощью параметров командной строки.
Используя jcmd , можно запускать определенные действия, при этом несколько команд разделяются символами новой строки.
Кроме того jcmd help дает информацию о том, какие команды имеются.
Вот несколько примеров:
Подробная информация обо всех загруженных классах
Гистограмма количества экземпляров
Создать дамп кучи.
Обзор использования кучи
Запустить сборку мусора
JFR.start name= settings= delay=20s duration=2m
Начать запись JDK JFR
JFR.dump name= filename=
Создать дамп JFR
Время выполнения JVM
Активные флаги JVM
Командная строка JVM
Визуальный вывод иерархии классов
Управление ведением журнала JVM
JDK Flight Recorder (jfr)
JDK Flight Recorder — это механизм для трассировки во время выполнения, который позволяет записывать различные события активности, происходящие в JVM, и соотносить их с активностью приложения.
Возможна трассировка всего, включая JIT-оптимизации, сборки мусора, точек сохранения и даже пользовательских событий.
Инструмент jfr позволяет читать и отображать файлы JDK Flight Recorder с помощью команд print , summary и metadata .
Выдачу результатов можно представить в удобочитаемом текстовом формате или JSON/XML ( --json, --xml ).
print представляет весь журнал событий
metadata показывает, какие события были записаны (классы событий)
summary показывает в виде гистограммы, какие события были записаны, как часто
Чтобы ограничить количество информации, категории можно фильтровать с помощью флага --categories "GC,JVM,Java*" , а события с помощью флага --events CPULoad,GarbageCollection или --events "jdk.*" .
К сожалению, это невозможно с помощью summary или metadata , только с помощью print .
Лучшим инструментом для оценки записей JFR, конечно же, является JDK Mission Control (JMC), который был выпущен как OpenSource, начиная с Java 11, а также предлагается другими поставщиками, такими как Azul.
jdeprscan
Поскольку в последние годы некоторые компоненты были исключены из JDK (discontinued), jdeprscan позволяет сканировать классы, каталоги или файлы jar для определения использования этих API.
С помощью jdeprscan --list --release 11 вы можете перечислить API, которые объявлены устаревшими (deprecated) в этом релизе.
Другие инструменты
Другие инструменты, такие как отладчик Java jdb , не так удобны, как возможности IDE для удобной отладки как на локальных, так и на удаленных компьютерах.
Заключение
Помощники, поставляемые с JDK, могут облегчить вашу жизнь, если вы знаете об их возможностях и о том, как их комбинировать друг с другом и с другими инструментами оболочки.
Напишем приложение «Список дел», при помощи которого пользователь можете заносить в список важные дела, которые нельзя забыть - купить батон хлеба, накормить кота, поздравить жену. Данные события будем сохранять в базе данных.
Логика программы проста - на основном экране приложения выводится список дел, а на втором происходит добавление нового события.
Создадим новый проект и сначала займемся классом, работающим с базой данных. В базе будет одна таблица с четырьмя колонками. А также добавим методы для управления данными - добавление, удаление, редактирование.
ToDoDatabase.java
Добавим несколько строковых ресурсов в res/values/strings.xml:
Разметка для основной активности (список и текстовая метка, когда список пуст):
Создадим разметку для отдельного элемента списка (list_row.xml):
Создадим вторую активность EditActivity, в которой будет происходить добавление новой задачи. Разметка для этой активности
Переходим к написанию кода. Сначала код для основной активности.
Осталось написать код для второй активности:
Запускаем проект и тестируем.
Если нужно удалить задачу из списка, то вызовите контекстное меню долгим нажатием и выберите пункт Удалить.
Вы заметили, что в проекте появились зачёркнутые строчки кода у метода startManagingCursor() и конструктора SimpleCursorAdapter, которые говорят, что эти конструкции устарели.
Примечание: В своё время я изучал этот пример, который попался на каком-то сайте. Позже я обнаружил, что на самом деле существует оригинал примера на известном ресурсе. Кстати, сейчас у автора примера проект переделан под новую платформу Android 4 с использованием контент-провайдера. Позже мы дважды переделаем пример. Сначала избавимся от устаревших конструкций, а потом задействуем контент-провайдер.
Программа — это набор (список) команд. Сначала выполняется первая команда, затем вторая, третья, и так далее. Когда все команды выполнены, программа завершается.
Какие именно команды могут быть в списке зависит от того, кто их выполняет : какие команды знает (и понимает) исполнитель . Собаке можно дать команду «Сидеть», «Голос», кошке — «Брысь», человеку — «Стой! Стрелять буду!», ну а роботу — «Работай! Работай, твою робомать».
Программы, написанные на языке Java, исполняет JVM (Java Virtual Machine — виртуальная машина Java ). JVM — это специальная программа, которая умеет исполнять программы, написанные на языке Java.
Список ее команд довольно обширен.
Например, этой командой можно вывести на экран надпись Робот — друг человека :
Но мы начнем не с команд, а с пары простых принципов. Знание нескольких принципов заменяет знание многих фактов.
Принцип первый: в языке программирования Java каждую команду принято писать с новой строки . В конце команды ставится точка с запятой .
Допустим, мы хотим 3 раза вывести на экран надпись Робот — друг человека . Вот как будет выглядеть код программы:
Принцип второй: программа не может просто состоять из команд. Команды языка Java должны находиться внутри функций, а функции — внутри классов.
Представьте себе диван. Диван не может быть сам по себе — он находится в какой-то комнате. Комната тоже не может существовать сама по себе — она находится в каком-то доме. Или же можно сказать, что дом делится на комнаты, а комнаты содержат вещи.
Так вот, команды — это мебель. В языке программирования Java команда не может быть сама по себе: она — часть функции (функции в Java еще называют методами). А метод (функция) — это часть класса . Иными словами, класс делится на методы , а методы содержат команды .
Java-программы состоят из классов, классы содержат методы, а методы — команды.
2. Структура типичной программы
Программы на языке Java состоят из классов . Классов может быть десятки тысяч. Минимальная программа — один класс. Для каждого класса заводится отдельный файл, имя которого совпадает с именем класса.
Допустим, вы решили создать класс, который будет описывать дом (дом по-английски — House). Тогда вам нужно создать класс House , который будет содержаться в файле House.java .
Если же вы решили описать в программе, например, кота (Cat — кот, по-английски), тогда вам нужно создать файл Cat.java и в нем описать класс Cat и т.д.
Внутри файлов содержится текст – код на языке программирования Java. Обычно код класса состоит из имени класса и тела класса . Тело класса помещается в фигурные скобки . Вот как может выглядеть класс House :
Тело класса может содержать переменные (их еще называют данными класса) и методы (функции класса). Выглядит это примерно так:
Ну или вот конкретный пример:
В примере выше a и b — это переменные, а main и pi — это методы.
3. Метод main()
Классы могут содержать переменные и методы, но не обязаны. Могут быть классы без переменных или без методов. И даже без методов и переменных одновременно. Хотя толку от таких классов немного.
Минимальная программа должна состоять минимум из одного класса , который должен содержать минимум один метод (функцию), с которого начинается выполнение программы. Такой метод должен иметь имя main .
Минимальная программа выглядит вот так:
Обратите внимание, что метод main в примере выше не содержит команд. Именно так: минимальная программа не содержит ни одной команды. На то она и минимальная.
У класса, с которого начинается программа, может быть любое имя , но у метода main , с которого начинает выполняться программа, всегда один и тот же вид :
Читайте также: