Научете Java от нулата

И така, искате да програмирате в Java? Това е чудесно и сте попаднали на правилното място. Серията Java 101 предоставя самоуправляващо се въведение в програмирането на Java, като се започне с основите и се обхванат всички основни концепции, които трябва да знаете, за да станете продуктивен Java разработчик. Тази поредица е техническа, с много примери за кодове, които да ви помогнат да разберете концепциите, докато вървим напред. Предполагам, че вече имате известен опит в програмирането, но не и в Java.

Тази първа статия представя платформата Java и обяснява разликата между трите й издания: Java SE, Java EE и Java ME. Също така ще научите за ролята на Java виртуалната машина (JVM) при разполагането на Java приложения. Ще ви помогна да настроите Java Development Kit (JDK) във вашата система, така че да можете да разработвате и стартирате Java програми и ще ви помогна да започнете с архитектурата на типично Java приложение. И накрая, ще научите как да компилирате и стартирате просто приложение Java.

Актуализиран за Java 12 и новата JShell

Тази поредица е актуализирана за Java 12 и включва кратко въведение в новото jshell: интерактивен инструмент за изучаване на Java и прототипиране на Java код.

изтегляне Вземете кода Изтеглете изходния код, например приложения в този урок. Създадено от Jeff Friesen за JavaWorld.

Какво е Java?

Можете да мислите за Java като език с общо предназначение, обектно-ориентиран език, който много прилича на C и C ++, но който е по-лесен за използване и ви позволява да създавате по-стабилни програми. За съжаление, това определение не ви дава много представа за Java. През 2000 г. Sun Microsystems (създателят на платформата Java) описва Java по следния начин: 

Java е прост, обектно-ориентиран, мрежово разбираем, интерпретиран, здрав, сигурен, неутрален в архитектурата, преносим, ​​високопроизводителен, многонишков, динамичен компютърен език.

Нека разгледаме всяко от тези определения поотделно.

Java е прост език . Java първоначално е моделирана след C и C ++, минус някои потенциално объркващи функции. Указатели, множествено наследяване на внедряване и претоварване на оператора са някои функции на C / C ++, които не са част от Java. Функция, която не е задължителна в C / C ++, но е от съществено значение за Java, е съоръжение за събиране на боклук, което автоматично възстановява обекти и масиви.

Java е обектно-ориентиран език . Обектно-ориентираният фокус на Java позволява на разработчиците да работят върху адаптирането на Java за решаване на проблем, вместо да ни принуждава да манипулираме проблема, за да отговорим на езиковите ограничения. Това е различно от структуриран език като C. Като пример, докато Java ви позволява да се съсредоточите върху обекти на спестовна сметка, C изисква да помислите отделно за състоянието на спестовната сметка (такъв баланс) и поведението (като депозит и теглене).

Java е разбираем за мрежата език . Разширената мрежова библиотека на Java улеснява справянето с мрежовите протоколи за контрол на предаването / протокол за интернет (TCP / IP) като HTTP (HyperText Transfer Protocol) и FTP (File Transfer Protocol) и опростява задачата за осъществяване на мрежови връзки. Освен това Java програмите могат да осъществяват достъп до обекти през TCP / IP мрежа чрез Uniform Resource Locators (URLs) със същата лекота, както бихте имали достъп до тях от локалната файлова система.

Java е интерпретиран език . По време на изпълнение Java програма косвено се изпълнява на основната платформа (като Windows или Linux) чрез виртуална машина (която е софтуерно представяне на хипотетична платформа) и свързаната среда за изпълнение. Виртуалната машина превежда байт кодовете на програмата Java (инструкции и свързани данни) в специфични за платформата инструкции чрез интерпретация. Тълкуването е актът да се разбере какво означава инструкция за байт код и след това да се изберат еквивалентни "консервирани" инструкции, специфични за платформата, които да се изпълнят. След това виртуалната машина изпълнява тези специфични за платформата инструкции.

Тълкуването улеснява отстраняването на грешки в дефектни Java програми, тъй като по време на изпълнение е налице повече информация за времето за компилация. Тълкуването също така дава възможност да се забави стъпката на връзката между частите на Java програма до време на изпълнение, което ускорява развитието.

Java е надежден език . Програмите на Java трябва да са надеждни, тъй като се използват както в потребителски, така и в критични приложения, вариращи от Blu-ray плейъри до системи за навигация или контрол на въздуха. Езиковите функции, които помагат за надеждността на Java, включват декларации, проверка на дублиращи се типове по време на компилация и време на изпълнение (за да се избегнат проблеми с несъответствието на версиите), истински масиви с автоматична проверка на границите и пропускане на указатели. (Вижте "Елементарни функции на езика на Java", за да започнете с типове езици на Java, литерали, променливи и др.)

Друг аспект на надеждността на Java е, че контурите трябва да се контролират от булеви изрази вместо целочислени изрази, където 0 е false и ненулева стойност е true. Например, Java не позволява цикъл в стил C, например, while (x) x++;защото цикълът може да не завърши там, където се очаква. Вместо това трябва изрично да предоставите булев израз, като например while (x != 10) x++;(което означава, че цикълът ще работи, докато xе равен на 10).

Java е сигурен език . Java програмите се използват в мрежови / разпределени среди. Тъй като Java програмите могат да мигрират и да се изпълняват на различни платформи на мрежата, е важно тези платформи да бъдат защитени от злонамерен код, който може да разпространява вируси, да краде информация за кредитни карти или да извършва други злонамерени действия. Функциите на езика Java, които поддържат стабилност (като пропускането на указатели), работят с функции за сигурност, като например модела за защита на Java пясъчника и криптиране с публичен ключ. Заедно тези функции предотвратяват вирусите и други опасни кодове да опустошават нищо неподозираща платформа.

На теория Java е защитена. На практика са открити и експлоатирани различни уязвимости в сигурността. В резултат Sun Microsystems тогава и Oracle сега продължават да издават актуализации на защитата.

Java е архитектурно неутрален език . Мрежите свързват платформи с различни архитектури, базирани на различни микропроцесори и операционни системи. Не можете да очаквате Java да генерира специфични за платформата инструкции и тези инструкции да бъдат „разбрани“ от всички видове платформи, които са част от мрежа. Вместо това Java генерира независими от платформата инструкции за байт кодове, които са лесни за интерпретация на всяка платформа (чрез нейното внедряване на JVM).

Java е преносим език . Архитектурният неутралитет допринася за преносимостта. Преносимостта на Java обаче има повече от независими от платформата инструкции за байт кодове. Помислете, че размерите на целочислените типове не трябва да варират. Например 32-битовият тип цяло число винаги трябва да бъде подписан и да заема 32 бита, независимо къде се обработва 32-битовото цяло число (например платформа с 16-битови регистри, платформа с 32-битови регистри или платформа с 64-битови регистри). Библиотеките на Java също допринасят за преносимостта. Където е необходимо, те предоставят типове, които свързват Java кода със специфични за платформата възможности по възможно най-преносимия начин.

Java е език с висока производителност . Тълкуването дава ниво на изпълнение, което обикновено е повече от достатъчно. За сценарии на приложения с много висока производителност Java използва компилация точно навреме, която анализира интерпретираните последователности от инструкции на байт кода и компилира често интерпретирани последователности от инструкции към специфични за платформа инструкции. Последващите опити за интерпретиране на тези последователности от инструкции на байт кода водят до изпълнение на еквивалентни инструкции, специфични за платформата, което води до повишаване на производителността.

Java е многонишков език . За да подобри производителността на програми, които трябва да изпълняват няколко задачи наведнъж, Java поддържа концепцията за изпълнение с резба . Например програма, която управлява графичен потребителски интерфейс (GUI), докато изчаква вход от мрежова връзка, използва друга нишка за извършване на чакането, вместо да използва GUI нишката по подразбиране за двете задачи. Това поддържа GUI отзивчив. Примитивите за синхронизация на Java позволяват на нишките безопасно да комуникират данни помежду си, без да повреждат данните. (Вижте програмиране с резба в Java, обсъдено другаде в серията Java 101.)

Java е динамичен език . Тъй като взаимните връзки между програмния код и библиотеките се случват динамично по време на изпълнение, не е необходимо да ги свързвате изрично. В резултат на това, когато дадена програма или една от нейните библиотеки се развие (например за отстраняване на грешки или подобряване на производителността), разработчикът трябва само да разпространи актуализираната програма или библиотека. Въпреки че динамичното поведение води до по-малко код за разпространение, когато настъпи промяна на версията, тази политика на разпространение може също да доведе до конфликти на версиите. Например разработчикът премахва тип клас от библиотека или го преименува. Когато дадена компания разпространява актуализираната библиотека, съществуващите програми, които зависят от типа на класа, ще се провалят. За да намали значително този проблем, Java поддържа тип интерфейс, което е като договор между две страни. (Вижте интерфейси, типове и други обектно-ориентирани езикови функции, обсъдени другаде в серията Java 101.)

Разопаковането на тази дефиниция ни учи на много неща за Java. Най-важното е, че разкрива, че Java е едновременно език и платформа. По-късно в този урок ще научите повече за компонентите на платформата Java - а именно виртуалната машина Java и средата за изпълнение на Java.

Три издания на Java: Java SE, Java EE и Java ME

Sun Microsystems пусна Java 1.0 комплект за разработка на софтуер (JDK) през май 1995 г. Първият JDK беше използван за разработване на настолни приложения и аплети, а Java впоследствие се разви, за да обхване програмирането на корпоративни сървъри и мобилни устройства. Съхраняването на всички необходими библиотеки в един JDK би направило JDK твърде голям за разпространение, особено защото разпространението през 90-те години беше ограничено от компактдискове с малък размер и бавни мрежови скорости. Тъй като повечето разработчици не се нуждаят от всеки последен API (разработчикът на настолни приложения едва ли ще има нужда от достъп до корпоративни Java API), Sun раздели Java на три основни издания. В крайна сметка те станаха известни като Java SE, Java EE и Java ME:

  • Java Platform, Standard Edition (Java SE) е платформата Java за разработване на клиентски приложения (които работят на настолни компютри) и аплети (които работят в уеб браузъри). Имайте предвид, че от съображения за сигурност аплетите вече не се поддържат официално.
  • Java Platform, Enterprise Edition (Java EE ) е платформата Java, изградена върху Java SE, която се използва изключително за разработване на корпоративни ориентирани сървърни приложения. Приложенията от страна на сървъра включват Java сървлети , които са Java програми, които са подобни на аплетите, но се изпълняват на сървър, а не на клиент. Сервлетите отговарят на API на Java Servlet.
  • Java Platform, Micro Edition (Java ME) също е изградена върху Java SE. Това е Java платформата за разработване на MIDlets , които са Java програми, които се изпълняват на мобилни информационни устройства, и Xlets , които са Java програми, които се изпълняват на вградени устройства.

Java SE е основната платформа за Java и е фокусът на серията Java 101. Примерите за кодове ще се основават на най-новата версия на Java по време на писането, Java 12.

Платформата Java и JVM

Java е едновременно език за програмиране и платформа за стартиране на компилиран Java код. Тази платформа се състои главно от JVM, но също така включва среда за изпълнение, която поддържа изпълнението на JVM на основната (родна) платформа. JVM включва няколко компонента за зареждане, проверка и изпълнение на Java код. Фигура 1 показва как се изпълнява Java програма на тази платформа. 

Джеф Фризън

В горната част на диаграмата има поредица от файлове на програмния клас, един от които е обозначен като файл на основния клас. Програмата на Java се състои поне от основния файл на класа, който е първият файл от класа, който се зарежда, проверява и изпълнява.

JVM делегира зареждането на класа на своя компонент на loadloader. Classloaders зареждат файловете от различни източници, като файлови системи, мрежи и архивни файлове. Те изолират JVM от тънкостите на натоварването в клас.

Зареденият файл на класа се съхранява в паметта и се представя като обект, създаден от Classкласа. След като бъде зареден, верификаторът на байт кода проверява различните инструкции за байт код, за да се увери, че те са валидни и няма да застрашат сигурността.

Ако байт кодовете на файла на класа не са валидни, JVM се прекратява. В противен случай неговият интерпретационен компонент интерпретира байтовия код по една инструкция в даден момент. Интерпретацията идентифицира инструкциите за байт код и изпълнява еквивалентни естествени инструкции.

Някои последователности от инструкции на байт кода се изпълняват по-често от други. Когато интерпретаторът открие тази ситуация, JVM компилаторът точно навреме (JIT) компилира последователността на байт кода в роден код за по-бързо изпълнение.

По време на изпълнение интерпретаторът обикновено среща заявка за изпълнение на байт-код на друг файл на класа (принадлежащ на програмата или на библиотека). Когато това се случи, loadloader зарежда файла на класа и верификаторът на байт кода проверява байт кода на заредения файл на класа, преди да бъде изпълнен. Също така по време на изпълнение, инструкциите за байт код могат да поискат JVM да отвори файл, да покаже нещо на екрана, да издаде звук или да изпълни друга задача, изискваща сътрудничество с родната платформа. JVM реагира, като използва своята мостна технология Java Native Interface (JNI), за да взаимодейства с родната платформа за изпълнение на задачата.