Всем привет! Эта статья немного запоздала у меня на сайте, так как вышли уже более сложные статьи, например, по фреймворку Spring, но не написать ее я не могу, тем более, что на моем канале уже давно лежит видео-версия данного материала.
Сегодня мы не просто создадим первое Java-приложение. Мы сделаем его без использования какой либо среды разработки (IDE), в текстовом редакторе. Итак, нам понадобится:
- текстовой редактор (я буду использовать Sublime Text 3);
- стандартная консоль операционной системы (в Линукс-системах — терминал, а в windows — cmd);
- заранее установленная jdk (у меня 1.8);
- пять минут Вашего времени.
Я буду использовать в своем уроке Linux (Mint), но все, что я покажу, можно проделать и на Windows, главное чтобы у вас были настроены все переменные среды, в частности правильно была прописана переменная JAVA_HOME.
Кстати, небольшое отступление. Если Вы планируете в будущем развиваться в Java, то, как показал мой даже не большой опыт, лучше сразу пересаживаться на Linux и изучать его. Почему?
Потому, что по мере углубления в профессию, Вы обязательно столкнетесь с тем, что в Вашей очередной компании будет несколько разных серверов, в том числе удаленных, на которых будут стоять брокеры очередей, базы данных, какие-то другие сервисы, коннекторы, либо Вам нужно будет что-то починить в приложении, разворачивать которое локально — это какие-то запредельные танцы с бубном и проще его отладить удаленно. Безусловно для Windows есть Bitvise, но все равно все это проще делать через ssh, autossh и тому подобное. То есть по факту Linux на много больше подходит для разработки чем Windows или Mac и сильно облегчает Вам жизнь.
Ну, а мы возвращаемся к нашему приложению. Итак, открываем консоль, создаем папку для нашего будущего проекта, например HelloWorld, внутри нее создаем папку src — это стандартная папка исходных кодов в любом Java-проекте и переходим в эту папку:
Далее мы запускаем наш текстовой редактор. В моем случае, я просто, перейдя в нужный каталог, запускаю указанный выше Sublime Text 3 командой subl и начинаю писать код нашего первого приложения.
Подробно рассказывать о языке Java и его синтаксисе я сейчас не буду, это не задача данной статьи. Но если в кратце: Java — это объектно-ориентированный язык программировани я (есть, например, еще функциональные). Основа данного типа языков — объекты. Все в этом мире есть объекты. Например: летающий аппарат (ЛА). ЛА можно в первом приближении поделить на разные типы.
Например: свободно парящие и приводимые в движение внешней силой. Вторые можно поделить на: самолеты, ракеты, различного вида аэростаты, воздушные шары. Самолеты можно поделить на реактивные, винтовые, турбовинтовые. Ну и так далее.
У каждого ЛА есть свойства, определяющие, конфигурирующие его: вес, размер, скорость, название модели. Эти свойства представлены как обычными числовыми примитивами (например, размер, скорость — это int (целое число), вес — double (дробное число), а название модели — String (строка)), так и семейством других объектов, например — материал.
То есть, у нас может быть отдельное дерево материалов, и какой-то из них может быть свойством ЛА. Другими словами, объекты в качестве свойств могут содержать другие объекты. Так же у объектов есть методы. Это как бы действия, глаголы. Например, метод «лететь». Методы могут принимать входные параметры:
лететь(int координатаА, int координатаБ)
Если метод ничего не возвращает, никакого результата своего выполнения, то перед его названием ставится ключевое слово void:
void fly(int a, int b)
Но метод может и возвращать что-либо, например, результат своего выполнения. В нашем случае — долетел, не долетел. Есть в Java булева переменная boolean, которая способна содержать только 2 значения ЛОЖЬ / ИСТИНА, то есть TRUE / FALSE. И тогда наш метод будет выглядеть так:
boolean fly(int a, int b) < // реализация метода >
boolean result = fly(100, 200);
Ну а теперь переходим к написаню кода нашей программы, и по ходу я дополню вышеизложенный рассказ комментариями уже по «боевому коду».
Итак, мы уже открыли текстовой редактор и в созданном новом документе вводим:
Несколько комментарий по коду:
class Main — это класс нашего приложения. Что такое класс? Класс — это как бы чертеж объекта, его описание. Про объекты — смотрите выше. Несколько правил: в Java принято, что на 1 файл 1 класс. То есть, написать вот так в одном файле:
public Main1 < // some code >public Main2 < // some code >
… нельзя. Так же нельзя в коде создать класс:
public Main < // some code >
, а файл сохранить как XYZ.java. То есть имя файла должно совпадать с именем класса. Но при этом в Яве есть вложенные классы и вот у одного внешнего класса может быть несколько вложенных, однако об этом позже.
Что такое public…? Это модификатор доступа. Очень-очень коротко про это: модификатор доступа это область видимости класса, метода, переменной.
Если мы говорим о классе, то он может быть только public или default. Класс объявленный без модификатора доступа является default и доступен только из других классов в одном пакете, класс имеющий модификатор public — доступен отовсюду. Про пакеты — это отдельная история, если объяснять на совсем «деревенском», то пакеты — это что-то типа аналога деления на папки, директории в операционной системе. Но, повторюсь — это очень обобщенное и не совсем верное объяснение.
Идем, дальше. Что такое public static void main(String[] args) <> ? Разбираем:
- public — как было замечено выше, модификатор доступа. Только для методов они еще могут быть, например, private (то есть доступны только внутри класса) или protected (то есть доступны внутри класса и его наследников).
- static — модификатор static для переменной или метода работает следующим образом. Обычная переменная или метод создаются отдельно для каждого экземпляра класса. Напомню, ключевое слово class — это только чертеж, описание класса. Чтобы «чертеж» использовать, по нему надо сделать «деталь». В Яве это называется разными терминами, например, «инициализировать» или сделать инстанс класса, экземпляр класса. В коде это может выглядеть так (например, мы хотим из какого-то другого класса обратится к классу Main):
Main main = new Main();
main — это переменная типа Main. new — зарезервированное ключевое слово, принуждающее компилятор создать инстанс того или иного класса. То есть, опять же, если совсем на пальцах. Представим что у нас есть чертеж самолета, который называется ЧертежСамолета, мы говорим компилятору:
ЧертежСамолета самолет = новый ЧертежСамолета();
Компилятор, создай мне самолет по ЧертежуСамолета, чтобы это был самолет того типа, который указан в ЧертежСамолет.
Так, собственно, о чем мы? Мы же о static, а не о самолетах. Таким образом, если мы захотим создать второй самолет, это будет:
ЧертежСамолет самолет2 = новый ЧертежСамолет ();
Представим себе, что у самолета есть свойство вес — weight. И давайте уже вернемся на английский. И если мы вернемся к вышеуказанному коду, то:
Рассмотрим элементы в constant_pool.
1-ый элемент:
Этот тег соответствует CONSTANT_Methodref, а значит дальше должно быть описание:
CONSTANT_Methodref_info u1 tag;
u2 class_index;
u2 name_and_type_index;
>
соответственно:
00 06
class_index, указывает на 6 элемент в constant_pool
00 0f
name_and_type_index, указывает на 15 элемент в constant_pool
Пока не понятно, на какой метод указывает эта ссылка и мы идем дальше:
2-ой элемент:
Это CONSTANT_Fieldref, а значит дальше ищем:
CONSTANT_Fieldref_info u1 tag;
u2 class_index;
u2 name_and_type_index;
>
И тут все очень похоже на предыдущий элемент, хотя не понятно что это за поле, в своем классе я вроде ничего такого не объявлял.
00 10
class_index в 16 элементе
00 11
name_and_type_index в 17 элементе
tag для CONSTANT_String
CONSTANT_String_info
получаем, что самое интересное лежит в 18 элементе:
00 12
Tag соответствующий ссылке на метод:
класс которого описан в 19 элементе
00 13
a название и тип в 20 элементе:
00 14
5-ый элемент:
Tag для CONSTANT_Class
название, которого в 21 элементе
00 15
6-ой элемент:
Cнова CONSTANT_Class
c названием в 22 элементе
00 16
Как мы помним 1-ый элемент constant_pool относится к этому классу.
7-ой элемент:
tag, CONSTANT_Utf8, первая строчка
Она должна соответствовать:
CONSTANT_Utf8_info u1 tag;
u2 length;
u1 bytes[length];
>
Тогда длина нашей строчки 6 байт:
00 06
А значение «»:
3c 69 6e 69 74 3e
Это особое название, так помечаются конструкторы.
8-ой элемент:
строчка длины 3 — «()V»:
00 03 28 29 56
Это описание нашего конструктора без параметров, который был упомянут в седьмом элементе.
9-ый элемент:
CONSTANT_Utf8
00 04 43 6f 64 65
10-ый элемент:
Строка LineNumberTable
01 00 0f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65
11-ый элемент
«main»:
01 00 04 6d 61 69 6e
12-ый элемент
«([Ljava/lang/String;)V»
01 00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56
13-ый элемент
«SourceFile»
01 00 0a 53 6f 75 72 63 65 46 69 6c 65
14-ый элемент
«App.java»:
01 00 08 41 70 70 2e 6a 61 76 61
15-ый элемент
Tag, соответствует CONSTANT_NameAndType
а значит нам понадобится
CONSTANT_NameAndType_info u1 tag;
u2 name_index;
u2 descriptor_index;
>
и тогда:
ссылка на 7 элемент
00 07
ccылка на 8 элемент
00 08
Учитывая что первый элемент ссылался на это, мы можем заключить что первым был объявлен конструктор класса без параметров. Название класса, мы должны найти в 22 элементе.
16-ый элемент:
Tag, для CONSTANT_Class
c названием в 23 элементе
00 17
17-ый элемент:
Tag, CONSTANT_NameAndType, со ссылкой на 24 и 25 элемент constant_pool
0c 00 18 00 19
18-ый элемент:
Ура «Hello world!»
01 00 0c 48 65 6c 6c 6f 20 77 6f 72 6c 64 21
19-ый элемент:
Tag, для CONSTANT_class c названием в 25-ом элементе
07 00 1a
20-ый элемент:
Tag CONSTANT_NameAndType cо ссылкой на 27 и 28 элемент
0c 00 1b 00 1c
21-ый элемент:
«hello/App»
01 00 09 68 65 6c 6c 6f 2f 41 70 70
22-ой элемент:
«java/lang/Object»
01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74
23-ий элемент:
«java/lang/System»
01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 53 79 73 74 65 6d
24-ый элемент:
«out»
01 00 03 6f 75 74
25-ый элемент:
«Ljava/io/PrintStream;»
01 00 15 4c 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d 3b
26-ой элемент:
«java/io/PrintStream»
01 00 13 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d
27-ой элемент:
«println»
01 00 07 70 72 69 6e 74 6c 6e
28-ой элемент:
«(Ljava/lang/String;)V»
01 00 15 28 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56
00 21
this_class
00 05
super_class
00 06
00 00 // interfaces_count 00 00 // fields_count
methods_count у нас 2 метода в классе, конструктор по умолчанию и метод main:
00 02
Method 1 — Constructor
00 01 — access_flags 00 07 — name_index 00 08 — descriptor_index 00 01 — attributes_count
Attribute 1
00 09 // name_index (Code) 00 00 00 1d // attribute_length 00 01 // max_stack 00 01 // max_locals 00 00 00 05 // code_length
Один из самых интересных аттрибутов с кодом нашего метода code[code_length], разбор инструкций отдельная большая тема:
2a // aload_0 b7 00 01 // invokespecial (Запустить первый метод в constant_pool) b1 // return
Аттрибут закончился и продолжается описание метода
00 00 // exception_table_length 00 01 // attributes_count 00 0a // attribute_name_index (LineNumberTable — 10 элемент) 00 00 00 06 // attribute_length 00 01 // line_number_table_length 00 00 // start_pc 00 03 // line_number
Method 2 — main
00 09 // access_flags 00 0b // name_index 00 0c // descriptor_index 00 01 // atributes_count
Attribute 1 код метода main
00 09 // name_index (Code) 00 00 00 25 // attribute_length 00 02 // max_stack 00 01 // max_locals 00 00 00 09 // code_length
b2 00 02 // getstatic 2, распутывая цепочку будет java.lang.System 12 03 // ldc 3 b6 00 04 // invokevirtual 4 b1 // return
00 00 // exception_table_length 00 01 // attributes_count 00 0a // attribute_name_index (LineNumberTable — 10 элент) 00 00 00 0a // attribute_length 00 02 // line_nuber_table_length 00 00 // start_pc 00 06 // line_number 00 08 // start_pc 00 07 // line_number
Описание методов закончено и идет описание атрибутов класса
00 01 // attributes_count 00 0d // name_index (SourceFile) 00 00 00 02 // attributes_length 00 0e // sourcefile_index(App.java)
Теперь когда мы закончили с по-байтовым разбором class файла, становится понятно как работает:
javap -c -s -verbose classes/hello/App.class
Он автоматически выводит тоже самое, что я выписал руками:
Classfile /. /classes/hello/App.class Last modified Aug 14, 2015; size 418 bytes MD5 checksum e9d96126a9f5bbd95f154f1a40d46b53 Compiled from «App.java» public class hello.App minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #6.#15 // java/lang/Object.»»:()V #2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #18 // Hello world! #4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #21 // hello/App #6 = Class #22 // java/lang/Object #7 = Utf8 #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 main #12 = Utf8 ([Ljava/lang/String;)V #13 = Utf8 SourceFile #14 = Utf8 App.java #15 = NameAndType #7:#8 // «»:()V #16 = Class #23 // java/lang/System #17 = NameAndType #24:#25 // out:Ljava/io/PrintStream; #18 = Utf8 Hello world! #19 = Class #26 // java/io/PrintStream #20 = NameAndType #27:#28 // println:(Ljava/lang/String;)V #21 = Utf8 hello/App #22 = Utf8 java/lang/Object #23 = Utf8 java/lang/System #24 = Utf8 out #25 = Utf8 Ljava/io/PrintStream; #26 = Utf8 java/io/PrintStream #27 = Utf8 println #28 = Utf8 (Ljava/lang/String;)V < public hello.App(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object.»»:()V 4: return LineNumberTable: line 3: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello world! 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 6: 0 line 7: 8 > SourceFile: «App.java»
А вот здесь можно посмотреть пример разбора class файла:
ClassFile(InputStream in, Attribute.Factory attributeFactory) throws IOException, ConstantPoolException
Источник: habr.com
Пишем Hello World на Java
Java – самая популярная платформа для программирования в мире. На этом языке программирования работает более 3 билионов устройств! Конечно же, самая популярная платформа – Androi, другие языки программирования здесь поддерживаются с трудом. Кроме Android-устройств, на Java работают настольные компьютеры, кнопочные телефоны (операционная система Symbian), а также другие устройства: Blu-Ray плееры, телевизоры, приставки… Так что Java – язык программирования, который подойдет для почти всех устройств.
Конечно, у этого языка есть и минусы – к примеру, медленная работа .jar файлов (исполняемых файлов Java). Также для настольных компьютеров требуется установка JRE, иначе приложения Java просто не запустятся.
Сейчас идет активная борьба между Java и C++, однако какой язык использовать – выбирать вам. Начнем!
Первый код на Java
class Code < public static void main (String[] args) throws java.lang.Exception < System.out.println («Hello, World!»); >>
Чтобы выполнить его, надо перейти по адресу ideone.com и вставить код в текстовое поле. При клике по кнопке “Run” в поде “stdout” выведется текст, который мы хотели вывести. Ура! Теперь можно поменять текст в кавычках на свой.
Важно! Пока что можно вывести только латиницу, для кириллицы понадобятся дополнительные функции!
Также код доступен по этой ссылке.
Разбор кода
В коде каждая строка что-нибудь да означает. Давайте разберемся, что именно!
Это – класс. Класс – это часть кода, отвечающая за определенную задачу, которая, в свою очередь, состоит из подзадач – функций. И классов, и функций может быть много, а может и мало – все зависит от масштабов программы. Сейчас класс один, но если их несколько, то должен быть главный класс – перед ним ставится ключевое слово public.
Это – главная функция класса. Она запускается первой. Функций может быть много, но main () должна присутствовать всегда. В скобках указаны аргументы – инструкции функции, с помощью которых она понимает, какие данные ей нужно принимать, и принимает их. Здесь это аргументы командной строки, т. е. указание на считывание данных с клавиатуры.
После аргументов указано ключевое слово throws с исключением – оно позволяет программе завершиться без фатальных для системы ошибок при возникновении неполадок в коде, здесь – языковых.
System.out.println («Hello, World!»);
Это – оператор вывода, то есть инструкция программе. Оператор println выводит заданную в скобках информацию – переменную или строку. Здесь это строка, поэтому она указана в кавычках.
Это весь код. Ну как, сложно?
Заключение
Java – современный, быстро развивающийся язык программирования. Выбор все равно стоит за вами, но здесь все зависит от предпочтений: если интересуют мобильные платформы или техника, то тогда Java, а если же нужно писать приложения под компьютеры, и важна скорость программы – тогда, несомненно, C++ или Python. Удачи вам!
Источник: gitjournal.tech