Java

Материал из Википедии — свободной энциклопедии
Перейти к навигацииПерейти к поиску
Эта статья — о языке программирования. О прикладной платформе на основе данного языка см. Java (программная платформа).
Не следует путать сJavaScript.
Java
Класс языка
Появился в23 мая1995
АвторДжеймс Гослинг и Sun Microsystems
РазработчикSun Microsystems, Oracle[1] и Джеймс Гослинг
Расширение файлов.java, .class,.jar, .jad, .jmod,.war,.ear
ВыпускJava SE 24[2] (18.03.2025)
Испытал влияниеC++, Си, Ада, Simula 67[вд], Smalltalk, Objective-C, Object Pascal, Оберон, Eiffel, Модула-3, Mesa[вд], Симула, C# и UCSD Pascal
Повлиял наAda,C#,Chapel,Clojure,ECMAScript,Fantom,Gambas,Groovy,Hack,Haxe,J#,Kotlin,PHP,Python,Scala,Seed7,Vala,JavaScript
ЛицензияGNU GPL[3]
Сайтjava.com
Логотип Викисклада Медиафайлы на Викискладе

Java[прим. 1] —строготипизированныйобъектно-ориентированный язык программирования общего назначения, разработанный компаниейSun Microsystems (в последующем приобретённой компаниейOracle). Разработка ведётся сообществом, организованным черезJava Community Process; язык и основные реализующие его технологии распространяются по лицензииGPL. Права наторговую марку принадлежат корпорацииOracle.

Приложения Java обычнотранслируются в специальныйбайт-код, поэтому они могут работать на любойкомпьютерной архитектуре, для которой существует реализациявиртуальной Java-машины. Дата официального выпуска — 23 мая 1995 года. Java занимает высокие места в рейтингах популярности языков программирования (2-е место в рейтингахIEEE Spectrum (2020)[4] иTIOBE (2021[5])).

Содержание

История создания

[править |править код]
Джеймс Гослинг

Изначально язык назывался Oak («Дуб»), разрабатывалсяДжеймсом Гослингом для программирования бытовых электронных устройств. Из-за того, что язык с таким названием уже существовал, Oak был переименован в Java[6]. Назван в честь маркикофе Java, которая, в свою очередь, получила наименование одноимённого острова (Ява), поэтому на официальной эмблеме языка изображена чашка с горячим кофе. Существует и другая версия происхождения названия языка, связанная саллюзией на кофемашину как пример бытового устройства, для программирования которого изначально язык создавался. В соответствии с этимологией в русскоязычной литературе с конца двадцатого и до первых лет двадцать первого века название языка нередко переводилось как Ява, а не транскрибировалось.

В результате работы проекта мир увидел принципиально новое устройство,карманный персональный компьютер Star7[7], который опередил своё время более чем на 10 лет, но из-за большой стоимости в 50 долларов не смог произвести переворот в мире технологии и был забыт.

Устройство Star7 не пользовалось популярностью, в отличие от языка программирования Java и его окружения. Следующим этапом жизни языка стала разработка интерактивного телевидения. Однако в 1994 году стало очевидным, что интерактивное телевидение было ошибкой.

С середины 1990-х годов язык стал широко использоваться для написания клиентских приложений исерверного программного обеспечения. Тогда же определённое распространение получила технологияJava-апплетов — графических Java-приложений, встраиваемых в веб-страницы; с развитием возможностейдинамических веб-страниц в 2000-е годы технология стала применяться редко.

Ввеб-разработке применяетсяSpring Framework; для документирования используется утилитаJavadoc.

Основные особенности языка

[править |править код]

Программы на Javaтранслируются вбайт-код Java, выполняемыйвиртуальной машиной Java (JVM) — программой, обрабатывающей байтовый код и передающей инструкции оборудованию какинтерпретатор.

Дюк — талисман Java

Достоинством подобного способа выполнения программ является полная независимость байт-кода отоперационной системы и оборудования, что позволяет выполнять Java-приложения на любом устройстве, для которого существует соответствующая виртуальная машина. Другой важной особенностью технологии Java является гибкая система безопасности, в рамках которой исполнение программы полностью контролируется виртуальной машиной. Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером), вызывают немедленное прерывание.

Часто к недостаткам концепции виртуальной машины относят снижение производительности. Ряд усовершенствований немного увеличил скорость выполнения программ на Java:

  • применение технологии трансляциибайт-кода вмашинный код непосредственно во время работы программы (JIT-технология) с возможностью сохранения версий класса в машинном коде,
  • обширное использованиеплатформенно-ориентированного кода (native-код) в стандартных библиотеках,
  • аппаратные средства, обеспечивающие ускоренную обработку байт-кода (например, технологияJazelle, поддерживаемая некоторыми процессорамиархитектуры ARM).

По данным сайта shootout.alioth.debian.org, для семи разных задач время выполнения на Java составляет в среднем в полтора-два раза больше, чем для C/C++, но при этом в некоторых случаях Java быстрее, а в отдельных случаях в 7 раз медленнее[8]. С другой стороны, для большинства из них потребление памяти Java-машиной было в 10—30 раз больше, чем программой на C/C++. Также примечательно исследование, проведённое компаниейGoogle, согласно которому отмечается существенно более низкая производительность и бо́льшее потребление памяти в тестовых примерах на Java в сравнении с аналогичными программами наC++[9][10][11].

Идеи, заложенные в концепцию и различные реализации среды виртуальной машины Java, вдохновили множество энтузиастов на расширение перечня языков, которые могли бы быть использованы для создания программ, исполняемых на виртуальной машине[12]. Эти идеи нашли также выражение в спецификации общеязыковой инфраструктурыCLI, заложенной в основу платформы.NET компаниейMicrosoft.

Классификация платформ Java

[править |править код]

Внутри Java существует несколько основных семейств технологий:

  • Java SE — Java Standard Edition — основное издание Java. Содержит компиляторы,API,Java Runtime Environment; подходит для создания пользовательских приложений, в первую очередь — для настольных систем.
  • Jakarta EE (ранее — Java EE (Enterprise Edition)) представляет собой набор спецификаций для созданияПО уровня предприятия. В 2017-м проект Java EE был переданEclipse Foundation, и тогда же его наименование изменилось на текущее[13][14]. Модули Java EE удалены из Java SE с 11-й версии[15].
  • Java ME — Java Micro Edition, создана для использования в устройствах, ограниченных по вычислительной мощности, например, вмобильных телефонах,КПК,встроенных системах;
  • Java Card — технология предоставляет безопасную среду для приложений, работающих насмарт-картах и других устройствах с очень ограниченным объёмом памяти и возможностями обработки.

Java и Microsoft

[править |править код]

КомпаниейMicrosoft была разработана собственная реализацияJVM под названиемMicrosoft Java Virtual Machine[англ.] (MSJVM)[16], включавшаяся в состав различныхоперационных систем, начиная сWindows 98 (также входила вInternet Explorer от версии 3 и выше, что позволяло использовать MSJVM в ОСWindows 95 иWindows NT 4 после установки IE3+ на данные ОС).

MSJVM имела существенные отличия от Sun Java, во многом ломающие основополагающую концепцию переносимости программ между разными платформами:

Тесная интеграция Java с DCOM иWin32 поставила под вопроскроссплатформенную парадигму языка. Впоследствии это явилось поводом для судебных исков со стороныSun Microsystems к Microsoft. Суд принял сторону компании Sun Microsystems. В конечном счёте между двумя компаниями была достигнута договорённость о возможности продления срока официальной поддержки пользователей нестандартной Microsoft JVM до конца 2007 года[16].

В 2005 году компанией Microsoft для платформы.NET был представлен Java-подобный языкJ#, не соответствующий официальной спецификации языка Java и исключённый впоследствии из стандартного инструментария разработчикаMicrosoft Visual Studio, начиная с Visual Studio 2008[17].

Java и Android

[править |править код]
Основная статья:Android

Язык Java активно используется для создания мобильных приложений под операционную систему Android. При этом программы компилируются в нестандартный байт-код для использования их виртуальной машинойDalvik (начиная сAndroid 5.0 Lollipop виртуальная машина заменена наART). Для такой компиляции используется дополнительный инструмент, а именноAndroid SDK (Software Development Kit), разработанный компаниейGoogle.

Разработку приложений можно вести в средеAndroid Studio,NetBeans, в средеEclipse.

Применения платформы Java

[править |править код]

Следующие успешные проекты реализованы с привлечением Java (J2EE) технологий:RuneScape,Amazon[18][19],eBay[20][21],LinkedIn[22],Yahoo![23].

Следующие компании в основном фокусируются на Java- (J2EE-) технологиях:SAP,IBM,Oracle. В частности,СУБДOracle Database включает JVM как свою составную часть, обеспечивающую возможность непосредственного программирования СУБД на языке Java, включая, например,хранимые процедуры[24].

Производительность

[править |править код]

Программы, написанные на Java, имеют репутацию более медленных и занимающих больше оперативной памяти, чем написанные на языке C[8]. Тем не менее, скорость выполнения программ, написанных на языке Java, была существенно улучшена с выпуском в 1997—1998 годах JIT-компилятора в версии 1.1 в дополнение к другим особенностям языка для поддержки лучшего анализа кода (такие, как внутренние классы, классStringBuffer[док. 1], упрощённые логические вычисления и так далее). Кроме того, была произведена оптимизация виртуальной машины Java — с 2000 года для этого используется виртуальная машинаHotSpot. По состоянию на февраль 2012 года код Java 7 приблизительно в 1,8 раза медленнее кода, написанного на языке Си[25].

Некоторые платформы предлагают аппаратную поддержку выполнения для Java[26]. К примеру, микроконтроллеры, выполняющие код Java на аппаратном обеспечении вместо программной JVM, а также основанные на ARM процессоры, которые поддерживают выполнение байт-кода Java через опцию Jazelle.

Основные возможности

[править |править код]

Основные идеи

[править |править код]

Примитивные типы

[править |править код]

В языке Java только 8 примитивных (скалярных, простых)типов:boolean,byte,char,short,int,long,float,double. Существует также вспомогательный девятый примитивный тип —void, однако переменные и поля такого типа не могут быть объявлены в коде, а сам тип используется только для описания соответствующего ему класса, для использования прирефлексии: например, с помощью классаVoid[док. 2] можно узнать, является ли определённый метод типаvoid:Hello.class.getMethod("main", String[].class).getReturnType() == Void.TYPE.

Длины и диапазоны значений примитивных типов определяются стандартом, а не реализацией, и приведены в таблице. Тип char сделали двухбайтовым для удобства локализации (один из идеологических принципов Java): когда складывался стандарт, уже существовалUnicode-16, но не Unicode-32. Поскольку в результате не осталось однобайтового типа, добавили новый тип byte, причём в Java, в отличие от других языков, он не является беззнаковым. Типыfloat иdouble могут иметь специальные значения+{\displaystyle +\infty },{\displaystyle -\infty } и «не число» (NaN). Для типа double они обозначаютсяDouble.POSITIVE_INFINITY,Double.NEGATIVE_INFINITY,Double.NaN; для типаfloat — так же, но с приставкойFloat вместоDouble. Минимальные и максимальные значения, принимаемые типамиfloat иdouble, тоже стандартизованы.

ТипДлина (в байтах)Диапазон или набор значений
boolean1 в массивах, 4 в переменных[27]true, false
byte1−128..127
char20..216−1, или 0..65535
short2−215..215−1, или −32768..32767
int4−231..231−1, или −2147483648..2147483647
long8−263..263−1, или примерно −9.2·1018..9.2·1018
float4-(2-2−23)·2127..(2-2−23)·2127, или примерно −3.4·1038..3.4·1038, а также{\displaystyle -\infty },{\displaystyle \infty }, NaN
double8-(2-2−52)·21023..(2-2−52)·21023, или примерно −1.8·10308..1.8·10308, а также{\displaystyle -\infty },{\displaystyle \infty }, NaN

Такая жёсткая стандартизация была необходима, чтобы сделать язык платформенно-независимым, что является одним из идеологических требований к Java. Тем не менее, одна небольшая проблема с платформенной независимостью всё же осталась. Некоторые процессоры используют для промежуточного хранения результатов 10-байтовыерегистры или другими способами улучшают точность вычислений. Для того, чтобы сделать Java максимально совместимой между разными системами, в ранних версиях любые способы повышения точности вычислений были запрещены. Однако это приводило к снижению быстродействия. Выяснилось, что ухудшение точности ради платформенной независимости мало кому нужно, тем более если за это приходится платить замедлением работы программ. После многочисленных протестов этот запрет отменили, но добавили ключевое словоstrictfp, запрещающее повышение точности. Начиная с Java 17, запрет на повышение точности снова начал действовать, а ключевое словоstrictfp было объявлено устаревшим[28].

Преобразования при математических операциях

[править |править код]

В языке Java действуют следующие правила:

  1. Если одиноперанд имеет типdouble, другой тоже преобразуется к типуdouble.
  2. Иначе, если один операнд имеет типfloat, другой тоже преобразуется к типуfloat.
  3. Иначе, если один операнд имеет типlong, другой тоже преобразуется к типуlong.
  4. Иначе оба операнда преобразуются к типуint.

Данный способ неявного преобразования встроенных типов полностью совпадает с преобразованием типов вСи/C++[29].

Объектные переменные, объекты, ссылки и указатели

[править |править код]

В языке Java имеются только динамически создаваемые объекты.Переменные объектного типа и объекты в Java — совершенно разные сущности. Переменные объектного типа являютсяссылками, то есть аналогамиуказателей на динамически создаваемые объекты. Это подчёркиваетсясинтаксисом описания переменных. Так, код наC++ может выглядеть следующим образом:

doublea[10][20];Foob(30);

Но то же самое на Java будет выглядеть совсем по-другому:

double[][]a=newdouble[10][20];Foob=newFoo(30);

При присваиваниях, передаче вподпрограммы и сравнениях объектные переменные ведут себя как указатели, то есть присваиваются, копируются и сравниваютсяадреса объектов. А при доступе с помощью объектной переменной к полям данных или методам объекта не требуется никаких специальных операцийразыменовывания — этот доступ осуществляется так, как если бы объектная переменная была самим объектом.

Объектными являются переменные любого типа, кроме примитивного. Явных указателей в Java нет. В отличие от указателей C, C++ и других языков программирования, ссылки в Java в высокой степени безопасны благодаря жёстким ограничениям на их использование.

  • Нельзя преобразовывать объект типаint или любого другого примитивного типа в указатель или ссылку и наоборот.
  • Над ссылками запрещено выполнять операции++,−−,+, или любые другие арифметические и логические операции (&&,||,^^).
  • Преобразование типов между ссылками жёстко регламентировано. За исключением ссылок на массивы, разрешено преобразовывать ссылки только между наследуемым типом и его наследником, причём преобразование наследуемого типа в наследующий должно быть явно задано, а во время выполнения производится проверка его осмысленности. Преобразования ссылок на массивы разрешены лишь тогда, когда разрешены преобразования их базовых типов, а также нет конфликтов размерности.
  • В Java нет операций взятия адреса (&) или взятия объекта по адресу (*).Амперсанд (&) означает всего лишь «побитовое и» (двойной амперсанд — «логическое и»). Однако для булевых типов одиночный амперсанд означает «логическое и», отличающееся от двойного тем, что цепь проверок не прекращается при получении в выражении значенияfalse[30]. Например,a == b && foo() == bar() не повлечёт вызововfoo() иbar() в случае, еслиa != b, тогда как использование& — повлечёт в любом случае.

Благодаря таким специально введённым ограничениям в Java невозможно прямое манипулирование памятью на уровне физических адресов (хотя определено значение ссылки, не указывающей ни на что:null).

Если нужен указатель на примитивный тип, используются классы-обёртки примитивных типов:Boolean,Byte,Character,Short,Integer,Long,Float,Double.

Дублирование ссылок и клонирование

[править |править код]

При присваивании не происходит копирования объекта, так как объектные переменные — ссылочные. Так, если написать

Foofoo,bar;...bar=foo;

то произойдёт копирование адреса из переменнойfoo в переменнуюbar. То естьfoo иbar будут указывать на одну и ту же область памяти, то есть на один и тот же объект; попытка изменить поля объекта, на который ссылается переменнаяfoo, будет менять объект, с которым связана переменнаяbar, и наоборот. Если же необходимо получить именно ещё однукопию исходного объекта, пользуются илиметодом (функцией-членом, в терминологии C++)clone(), создающим копию объекта, или (реже) копирующимконструктором (конструкторы в Java не могут быть виртуальными, поэтому экземпляр класса-потомка будет неправильно скопирован конструктором класса-предка; метод клонирования вызывает нужный конструктор и тем самым позволяет обойти это ограничение).

Методclone()[док. 3] требует, чтобы класс реализовывалинтерфейсCloneable[док. 4]. Если класс реализует интерфейсCloneable, по умолчаниюclone() копирует все поля (мелкая копия). Если требуется не копировать, а клонировать поля (а также их поля и так далее), надо переопределять методclone(). Определение и использование методаclone() часто является нетривиальной задачей[31].

Инициализация переменных

[править |править код]

Все переменные или требуют явного определения, или автоматически заполняются нулями (0,null,false). Таким образом, исчезаютгейзенбаги, связанные со случайным использованием неинициализированной памяти, характерные для низкоуровневых языков вродеСи.

Сборка мусора

[править |править код]

В языке Java невозможно явное удаление объекта из памяти — вместо этого реализованасборка мусора. Традиционным приёмом, дающим сборщику мусора «намёк» на необходимость освобождения памяти, является присваивание переменной значенияnull, что может оказаться эффективным при необходимости освободить более не требующийся объект, ссылка на который хранится в долгоживущем объекте[32]. Это, однако, не значит, что объект, заменённый значениемnull, будет немедленно удалён, но есть гарантия, что этот объект будет удалён в будущем. Данный приём всего лишь устраняет ссылку на объект, то есть отвязывает указатель от объекта в памяти. При этом следует учитывать, что объект не будет удалён сборщиком мусора, пока на него указывает хотя бы одна ссылка из используемых переменных или объектов. Существуют также методы для инициации принудительной сборки мусора, но не гарантируется, что они будут вызваны исполняющей средой, и их не рекомендуется использовать для обычной работы. Помимо периодических сборок мусора стоит отметить так называемую «общую сборку мусора» (STW,англ. Stop The World), которая может привести ко временному «подвисанию» исполняемой программы[33].

В Java используется несколько сборщиков мусора (Serial GC, Parallel GC, G1, ZGC), какой из них используется по умолчанию — зависит от версииIDE. Чтобы выбрать какой-то определённый, нужно запуститьJRE с ключом командной строки «-XX:+Use<имя сборщика>GC -jar <имя-jar-файла.jar>», например, вызов «java -XX:+UseG1GC -jar Application.java» приведёт к сборке мусора его сборщиком G1[34].

Классы и функции

[править |править код]

Java не является процедурным языком: любая функция может существовать только внутри класса. Это подчёркивает терминология языка Java, где нет понятий «функция» или «функция-член» (англ. member function), а толькометод. В методы превратились и стандартные функции. Например, в Java нет функцииsin(), а есть методMath.sin() классаMath (содержащего, кромеsin(), методыcos(),exp(),sqrt(),abs() и многие другие).

Как и в языкеC, любая исполняемая программа на Java должна иметьточку входа, которой является метод main — он должен/может быть единственным в программе и, в отличие от Си, всегда статическим. При этом, начиная с Java 21, в которой были экспериментально введены безымянные классы, допускается определять этот метод, не определяя имени главного класса.

Конструкторы в Java не считаются методами. Деструкторов в Java не существует, а методfinalize() ни в коем случае нельзя считать аналогом деструктора.

Конструкторы

[править |править код]

Конструктор — это специальный метод, который обязательно вызывается при создании нового объекта, то есть объект (экземпляр класса) не может быть создан без вызова конструктора класса. Не всегда удобно инициализировать все переменные класса при создании его экземпляра, поэтому переменные экземпляра часто объявляют внутри тела конструктора, а инициализируют как аргументы конструктора при создании экземпляра класса. Иногда проще, чтобы какие-то значения были бы созданы по умолчанию при создании объекта. В таком случае переменные объявляются и инициализируются внутри тела конструктора.

Конструктор инициализирует объект непосредственно во время создания. Имя конструктора совпадает с именем класса, включая регистр, а по синтаксису конструктор похож на метод без возвращаемого значения.

privateintCat();// так выглядит метод по имени CatCat();// так выглядит конструктор класса Cat

В отличие от метода, конструктор никогда ничего не возвращает.

Конструктор определяет действия, выполняемые при создании объекта класса, и является важной частью класса. Как правило, программисты стараются явно указать конструктор. Если явного конструктора нет, то Java автоматически создаст его (пустым) для использования по умолчанию.

В качестве примера можно рассмотреть некий классBox, представляющий собой описание коробки. Конструктор класса просто установит начальные размеры для коробки.

classBox{intwidth;// ширина коробкиintheight;// высота коробкиintdepth;// глубина коробки// КонструкторBox(inta,intb){width=a;height=b;depth=10;}// вычисляем объём коробкиintgetVolume(){returnwidth*height*depth;}}

Статические методы и поля

[править |править код]

В Java (как и в C++) используютсястатические поля истатические методы (англ. static method — в теории программирования их также называют методами класса), которые задаются при помощи ключевого словаstatic. Статические поля (переменные класса) имеют тот же смысл, что и в C++: каждое такое поле является собственностью класса, поэтому для доступа к статическим полям не требуется создавать экземпляры соответствующего класса.

Например, математические функции, реализованные в классеMath[док. 5], представляют собой как раз статические методы данного класса. Поэтому их можно вызывать напрямую из класса, не создавая его экземпляра, например:

doublex=Math.sin(1);

Создание экземпляра статического класса запрещают с помощью приватного конструктора. Например, создание экземпляра классаMath приведёт к ошибке на этапе компиляции:

Mathm=newMath();// Error: Math() has private access in java.lang.Mathdoublex=m.sin(1);// Метода sin у объекта не существовало бы, т. к. он статичный

Поскольку статические методы существуют независимо от объектов (экземпляров класса), они не имеют доступа к обычным (не статическим) полям и методам данного класса. В частности, при реализации статического метода недопустимо использовать идентификаторthis.

Возможность статического импорта позволяет вызывать статические функции и константы без указания класса. Пример без статического импорта:

doublex=Math.sin(Math.tan(Math.sqrt(y))+Math.floor(24.5))+Math.cos(42*Math.PI);

Тот же пример, но со статическим импортом:

import staticjava.lang.Math.*;...doublex=sin(tan(sqrt(y))+floor(24.5))+cos(42*PI);

Завершённость (final)

[править |править код]

Ключевое словоfinal (финальный) имеет разные значения при описании поля, метода или класса.

  1. Финальноеполе класса инициализируется при описании или в конструкторе класса (а статическое поле — в статическом блоке инициализации). Впоследствии его значение не может быть изменено. Если статическое поле класса или переменная проинициализированы константным выражением, они рассматриваются компилятором какименованная константа; в таком случае их значение может быть использовано воператорахswitch (для констант типовint иString, в том числе — элементовперечислений), а также для условной компиляции (для констант типаboolean) при использовании соператоромif.
  2. Значениялокальных переменных, а такжепараметров метода, помеченных ключевым словомfinal, не могут быть изменены после присвоения. При этом их значения могут использоваться внутрианонимных классов.
  3. Метод класса, отмеченный словомfinal, не может быть переопределён при наследовании. В случаестатического метода с модификаторомfinal метод не может быть скрыт (hide) методом дочернего класса при наследовании.
  4. Финальныйкласс не может иметь наследников.

Абстрактность

[править |править код]

В Java методы, не объявленные явно какstatic,final илиprivate, являютсявиртуальными в терминологии C++: при вызове метода, по-разному определённого в базовом и наследующем классах, всегда производится проверка времени выполнения.

Абстрактным методом (модификаторabstract) в Java называется метод, для которого заданы параметры и тип возвращаемого значения, но не задано тело. Абстрактный метод определяется в классах-наследниках. Аналог абстрактного метода в C++ — чисто виртуальная функция (pure virtual function). Для того чтобы в классе можно было описывать абстрактные методы, сам класс тоже должен быть описан как абстрактный. Объекты абстрактного класса создавать нельзя.

Интерфейсы

[править |править код]

Высшей степенью абстрактности в Java является интерфейс (модификаторinterface). Интерфейс содержит преимущественно абстрактные методы, имеющие всеобщий уровень доступа: описателиabstract иpublic для них даже не требуются. Однако с версий Java 8 и 9 были введены возможности использования в интерфейсах

— Java 8: статических (static) методов и методов по умолчанию (default);

— Java 9: методов, имеющих уровень доступаprivate.

Эти методы содержат тело, а значит абстрактными не являются, но в конкретной реализации интерфейсаdefault-методы могут быть переопределены.

Интерфейс в Java не считается классом, хотя, по сути, является полностью абстрактным классом.

Класс может наследовать/расширять (extends) другой класс илиреализовывать (implements) интерфейс. Интерфейсы же могут наследовать/расширять другие интерфейсы. В Java класс не может наследовать более одного класса, зато может реализовывать несколько интерфейсов. Множественное наследование интерфейсов не запрещено — один интерфейс может наследоваться от нескольких.

С версии Java 15 (экспериментально, официально — с версии Java 17) добавлена возможность использования запечатанных (sealed) классов/интерфейсов, при объявлении которых, с помощью ключевого словаpermits, можно указывать, какие классы/интерфейсы могут наследовать данный запечатанный класс/интерфейс.

Интерфейсы можно использовать в качестве типов параметров методов. Нельзя создавать экземпляры интерфейсов.

Маркерные интерфейсы
[править |править код]

В Java есть интерфейсы, которые не содержат методов для реализации, а специальным образом обрабатываются JVM:Cloneable,Serializable,RandomAccess,Remote.

Шаблоны в Java (generics)

[править |править код]

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

// Объявление обобщённого классаclassGenericClass<E>{EgetFirst(){...}voidadd(Eobj){...}}// Использование обобщённого класса в кодеGenericClass<String>obj=newGenericClass<>();obj.add("qwerty");Stringp=obj.getFirst();

Допускается обобщённое объявление классов, интерфейсов и методов. Кроме того, синтаксис поддерживает ограниченные объявления типов-параметров: указание в объявлении конструкции вида<T extends A & B & C...> требует, чтобы тип-параметр T реализовывал интерфейсы A, B, C и так далее.

В отличие от шаблонов C#, шаблоны Java не поддерживаются средой исполнения — компилятор просто создаёт байт-код, в котором никаких шаблонов уже нет. Реализация шаблонов в Java принципиально отличается от реализации аналогичных механизмов в C++: компилятор не порождает для каждого случая использования шаблона отдельный вариант класса или метода-шаблона, а просто создаёт одну реализацию байт-кода, содержащую необходимые проверки и преобразования типов. Это приводит к ряду ограничений использования шаблонов в программах на Java.

Проверка принадлежности к классу

[править |править код]

В Java можно явно проверить, к какому классу принадлежит объект. Выражениеfoo instanceof Foo равноtrue, если объектfoo принадлежит классуFoo или его наследнику, или реализует интерфейсFoo (или, в общем виде, наследует класс, который реализует интерфейс, который наследуетFoo).

Далее функцияgetClass()[док. 6], определённая для всех объектов, выдаёт объект типаClass<?>. Для каждого класса создаётся не более одного описывающего его объекта типаClass, поэтому эти объекты можно сравнивать. Так, например,foo.getClass() == bar.getClass() будет истинно, если объектыfoo иbar принадлежат к одному классу.

Кроме того, объект типаClass<?> любого типа можно получить так:Integer.class,Object.class.

Прямое сравнение классов не всегда является оптимальным средством проверки на принадлежность к классу. Зачастую вместо него используют функциюisAssignableFrom(). Эта функция определена у объекта типаClass и принимает объект типаClass<?> в качестве параметра. Таким образом, вызовFoo.class.isAssignableFrom(Bar.class) вернётtrue в случае, еслиFoo является предком классаBar. Так как все объекты являются потомками типаObject, вызовObject.class.isAssignableFrom() всегда вернётtrue.

В паре с упомянутыми функциями объекта типаClass используются также функцииisInstance[док. 7] (эквивалентноinstanceof), а такжеcast() (преобразует параметр в объект выбранного класса).

Обработка ошибок

[править |править код]

Обработка ошибок в Java похожа на обработку ошибок вC++ за исключением необходимости в блокеfinally. Данное отличие обусловлено тем, что Java не может придерживаться концепцииRAII из-за наличия сборщика мусора, а автоматическое освобождение ресурсов в деструкторе может идти в непредсказуемом порядке через произвольные промежутки времени.

Осуществляется обработка ошибок с помощью операторовtry,catch иfinally. Выбрасываемая ошибка описывается объектом определённого класса, наследующегося отThrowable[док. 8] и соответствующего типу ошибки. Внутрь блокаtry помещается код, который может выбросить исключение, а блокcatch отлавливает заданные программистом типы ошибок. При этом можно указывать более одного блокаcatch для обработки различных классов ошибок, или multi-catch для обработки нескольких ошибок. Блокfinally является необязательным, но при наличии выполняется независимо от возникновения ошибки и предназначен для освобождения выделенных в ходе работы блокаtry ресурсов.

Начиная с Java 7 поддерживается интерфейсAutoCloseable[док. 9], который позволяет реализовывать классы, автоматически освобождающие ресурсы. Объекты подобных классов требуется создавать в круглых скобках перед блокомtry. Простым примером автоматического освобождения ресурсом может служить чтение содержимого файла:

importjava.io.*;publicclassMain{publicstaticvoidmain(String[]args)throwsIOException{if(args.length<2){System.err.println("Не указано имя файла.");return;}Stringfilename=args[1];// Открытый файл будет автоматически закрыт по ошибкеtry(BufferedReaderreader=newBufferedReader(newFileReader(filename))){Stringline;for(intn=1;(line=reader.readLine())!=null;++n){System.out.println(n+": "+line);}}catch(FileNotFoundExceptione){System.err.println("Указанный файл не найден.");}// finally {//     reader.close(); // автоматическое закрытие ресурса// }}}

Java придерживается концепции обязательного указания классов ошибок, которые может выбросить метод. Делается это с помощью ключевого словаthrows после описания метода. Если в методе не указать класс исключения (или его предка), которое может быть выброшено из метода, то это вызовет ошибку компиляции. Концепция должна была позволить делать код самодокументируемым, обозначая, какие исключения может выбросить тот или иной метод, но на практике редко себя оправдывает, поскольку в силу разных обстоятельств программист может указать в качестве выбрасываемого исключения классException либо заключить проблемные части метода в блокtry...catch для игнорирования отдельных ошибок, либо — в блокtry...finally, скрывая все возможные ошибки. Недостатком концепции также является и то, что программист сам должен определять и прописывать исключения, которые может выбрасывать метод[35].

Пространство имён

[править |править код]
Основная статья:Пространство имён (программирование)

Идея пространств имён воплощена вJava-пакетах.

Название Java-пакета создаётсялатиницей (используется нижний и верхний регистр) сцифрами (они не должны быть первыми в строке) и знаком подчёркивания (он не должен быть первым и последним в строке), не являющейся инструкциями языка (например,if,null), разделённой точками.

Правильные примеры названий:

  • project.types.net.media
  • a0.a_b.canrepeat.canrepeat.UPPERCASE.RaNdOmCaSe (хотя нежелательно, из-за нечитабельности)

Неправильные примеры названий:

  • doubledots..something (две точки подряд)
  • нестандартный.язык (не латиница)
  • 0first.characret.is.number (число в начале)
  • contains.white space (пробел вместо точки)
  • true.asd (содержитtrue, см. выше)

Пакеты содержат классы, интерфейсы, перечисления, аннотации (и т. д.), имена которых тоже создаются латиницей (используется нижний и верхний регистр) с цифрами (они не должны стоять первыми в строке). Публичный класс, интерфейс (и т. д.) в одном файле может быть только один. Имя публичного класса, интерфейса (и т. д.) в файле должно совпадать с названием файла. Каждый класс имеет своё пространство имён для функций, переменных и подклассов, подинтерфейсов (и т. д.), причём получить подкласс класса можно с помощьюOuterClass.InnerClass, а можно — с помощьюOuterClass$InnerClass, поэтому использование символа доллара в названии класса не рекомендуется.

Примеры программ

[править |править код]

Код программы «Hello, world!».

classHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello, world!");}}

Обобщения:

Пример использования обобщений
importjava.util.List;importjava.util.ArrayList;publicclassSample{publicstaticvoidmain(String[]args){// Создание объекта по шаблону.List<String>strings=newArrayList<>();strings.add("Hello");strings.add("world");strings.add("!");for(varstring:strings){System.out.print(string+" ");}}}

Рефлексия:

Пример использования рефлексии
importjava.lang.reflect.Field;importjava.lang.reflect.Method;classTestClass{privateintvalue;publicintgetValue(){returnvalue;}publicvoidsetValue(intvalueIn){this.value=valueIn;}}publicclassMain{publicstaticvoidmain(String[]args){vartestClass=newTestClass();for(varfield:testClass.getClass().getDeclaredFields()){System.out.printf("name:%s, type:%s \n",field.getName(),field.getType().getCanonicalName());}for(varmethod:testClass.getClass().getDeclaredMethods()){System.out.printf("name:%s, return type:%s  \n",method.getName(),method.getReturnType().getCanonicalName());}}}

Аннотации:

Пример использования аннотаций
importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfaceMyAnnotation{publicbooleanvalue()defaultfalse;}@MyAnnotation(value=true)publicclassTestClass{}publicclassMain{publicstaticvoidmain(String[]args){vartestClass=newTestClass();varmyAnnotation=testClass.getClass().getAnnotation(MyAnnotation.class);if(myAnnotation!=null){System.out.printf("value:%s \n",myAnnotation.value());}}}

Средства разработки ПО

[править |править код]
  • JDK — помимо набора библиотек для платформJava SE иJava EE, содержит компилятор командной строки javac и набор утилит, так же работающих в режиме командной строки.
  • NetBeans IDE — свободная интегрированная среда разработки для всех платформ Java —Java ME,Java SE иJava EE. ПропагандируетсяOracle, владельцем технологии Java, как базовое средство для разработки ПО на языке Java и других языках (C,C++,PHP,Fortran и др.).
  • Eclipse IDE — свободная интегрированная среда разработки дляJava SE,Java EE иJava ME[36]. ПропагандируетсяIBM, одним из важнейших разработчиков корпоративного ПО, как базовое средство для разработки ПО на языке Java и других языках (C,C++,Ruby,Fortran и др.).
  • IntelliJ IDEA — среда разработки для платформJava SE,Java EE иJava ME. Разработчик — компанияJetBrains. Распространяется в двух версиях: свободной бесплатной (Community Edition) и коммерческой проприетарной (Ultimate Edition).
  • JDeveloper — среда разработки для платформJava SE,Java EE иJava ME. Разработчик — компанияOracle.
  • BlueJ — среда разработки программного обеспечения на языке Java, созданная в основном для использования в обучении, но также подходящая для разработки небольших программ.
  • Geany —свободнаясреда разработки программного обеспечения, написанная с использованиембиблиотекиGTK2.

См. также

[править |править код]
В родственных проектах

Примечания

[править |править код]

Комментарии

[править |править код]
  1. Произносится на английском как/ˈdʒɑːvə/, «Джава». В русском языке помимо «Джава» встречается транслитерация «Ява», но правообладатели торговой марки предпочитают первую транслитерацию.

Документация

[править |править код]

Источники

[править |править код]
  1. 12https://www.oracle.com/java/
  2. Oracle Releases Java 24 . Дата обращения: 27 марта 2025.
  3. https://www.lemondeinformatique.fr/actualites/lire-java-open-source-c-est-fait-et-c-est-en-gpl-21350.html
  4. Top Programming Languages 2020.IEEE Spectrum (англ.).Архивировано 18 января 2021. Дата обращения: 14 февраля 2021.
  5. TIOBE Index | TIOBE — The Software Quality Company . www.tiobe.com. Дата обращения: 19 ноября 2018. Архивировано 25 февраля 2018 года.
  6. Buyya. Object-oriented Programming with Java: Essentials and Applications. — Tata McGraw-Hill Education, 2009. — 678 с. —ISBN 9780070669086. — [Архивировано 12 ноября 2018 года.]
  7. Star7: с чего начиналась Java . Дата обращения: 2 октября 2022. Архивировано 2 октября 2022 года.
  8. 12Java 6 -server speed ÷ C++ GNU g++ speed | Computer Language Benchmarks Game . Дата обращения: 4 марта 2010. Архивировано изоригинала 14 июня 2011 года.
  9. Metz, Cade. Google pits C++ against Java, Scala, and Go (англ.). The Register (3 июня 2011). Дата обращения: 5 июня 2011. Архивировано 21 августа 2011 года.
  10. Loop Recognition in C++/Java/Go/Scala (0.3 МБ)Архивная копия от 16 ноября 2011 наWayback Machine
  11. В Google провели сравнение производительности C++, Java, Go и Scala . Дата обращения: 5 июня 2011. Архивировано 8 июня 2011 года.
  12. Robert Tolksdorf. Programming languages for the Java Virtual Machine JVM (англ.). is-research GmbH. — Онлайн-каталог альтернативных языков и языковых расширений для JVM. Дата обращения: 5 июня 2009. Архивировано 21 августа 2011 года.
  13. Delabassee, David.Opening Up Java EE - An Update.Архивировано 26 ноября 2018. Дата обращения: 25 ноября 2018.
  14. And the Name Is….Life at Eclipse (англ.). 26 февраля 2018.Архивировано 26 ноября 2018. Дата обращения: 25 ноября 2018.
  15. JEP 320: Remove the Java EE and CORBA Modules . openjdk.java.net. Дата обращения: 25 ноября 2018. Архивировано 24 ноября 2018 года.
  16. 12Microsoft Java Virtual Machine Support (англ.). Microsoft (12 сентября 2003). — Официальное заявление Microsoft о программе поддержки MSJVM. Дата обращения: 9 октября 2010. Архивировано 21 августа 2011 года.
  17. Visual J#  (рус.). Microsoft (ноябрь 2007). — Официальная информация Microsoft об исключении J# из комплекта Visual Studio 2008. Дата обращения: 10 октября 2010. Архивировано 21 августа 2011 года.
  18. Todd Hoff. Amazon Architecture (англ.) (18 сентября 2007). — Обсуждение архитектуры Amazon с использованием Java-технологий. Дата обращения: 6 июня 2009. Архивировано 28 февраля 2009 года.
  19. Amazon Elastic Compute Cloud (Amazon EC2) (англ.). Amazon Web Services LLC. — Описание технологии и возможностей Amazon EC2 как веб-сервиса. Дата обращения: 6 июня 2009. Архивировано 21 августа 2011 года.
  20. Todd Hoff. eBay Architecture (англ.) (27 мая 2008). — Обсуждение архитектуры eBay на платформе Java. Дата обращения: 6 сентября 2009. Архивировано 21 августа 2011 года.
  21. Randy Shoup, Dan Pritchett. The eBay Architecture (англ.). SD Forum 2006. ??? (29 ноября 2006). — Презентация по истории развития архитектуры eBay. Дата обращения: 6 июня 2009. Архивировано 21 августа 2011 года.
  22. Brian Guan. The LinkedIn Blog. Blog Archive. Grails at LinkedIn (англ.). LinkedIn.com (11 июня 2008). — История создания системы LinkedIn на основе Java-технологии Grails. Дата обращения: 5 июня 2009. Архивировано 21 августа 2011 года.
  23. Hadoop and Distributed Computing at Yahoo! (англ.). Yahoo!. — Стартовая страница Java-технологии распределённого обслуживания Hadoop на портале разработчиков Yahoo! Дата обращения: 21 июня 2009. Архивировано 21 августа 2011 года.
  24. OracleJVM and Java Stored Procedures (англ.). Oracle Inc.. — Раздел портала Oracle, посвящённый технологиям Java в составе сервера СУБД Oracle. Дата обращения: 5 июня 2009. Архивировано 21 августа 2011 года.
  25. Ubuntu: Intel® Q6600® quad-core Computer Language Benchmarks . Архивировано 22 июня 2012 года.
  26. Wolfgang Puffitsch, Martin Schoeberl. picoJava-II in an FPGA (англ.) // DTU Library. — 2007. Архивировано 2 декабря 2018 года.
  27. JVM не имеет поддержки для переменных типа boolean, поэтому они представляются в виде значений типа int. Однако массивы boolean[] поддерживаются.VM Spec The Structure of the Java Virtual MachineАрхивная копия от 24 ноября 2011 наWayback Machine
  28. JEP 306: Restore Always-Strict Floating-Point Semantics (англ.). Дата обращения: 21 ноября 2022. Архивировано 21 ноября 2022 года.
  29. Бьярн Страуструп. Язык программирования C++ = The C++ Programming Language. — М.—СПб.: Бином, Невский диалект, 2008. — 1104 с. —5000 экз. —ISBN 5-7989-0226-2;ISBN 5-7940-0064-3;ISBN 0-201-70073-5.
  30. Джеймс Гослинг, Билл Джой, Гай Стил, Гилад Брача, Алекс Бакли, Даниел Смит. Java Language Specification. Chapter 15. Expressions (англ.). docs.oracle.com. Дата обращения: 1 декабря 2018. Архивировано 1 декабря 2018 года.
  31. Java API Reference. Class Object (англ.). docs.oracle.com. Дата обращения: 26 ноября 2018. Архивировано 26 ноября 2018 года.
  32. Scott Oaks. Java Performance: The Definitive Guide: Getting the Most Out of Your Code. — "O'Reilly Media, Inc.", 2014-04-10. — 425 с. —ISBN 9781449363543. — [Архивировано 21 июля 2021 года.]
  33. Garbage collection  (12 февраля 2024). Дата обращения: 6 февраля 2025.
  34. JVM Garbage Collectors  (11 мая 2024). Дата обращения: 4 февраля 2025.
  35. The Trouble with Checked Exceptions . www.artima.com. Дата обращения: 21 декабря 2018. Архивировано 8 января 2019 года.
  36. Pulsar - Eclipse Mobile Tools Platform (англ.). Eclipse. — Проект eclipse для мобильных разработчиков. Дата обращения: 23 марта 2011. Архивировано 21 августа 2011 года.

Литература

[править |править код]
  • Герберт Шилдт. Java. Полное руководство, 10-е издание = Java. The Complete Reference, 10th Edition. —М.:«Диалектика», 2018. — 1488 с. —ISBN 978-5-6040043-6-4.
  • Кей С. Хорстманн. Java SE 9. Базовый курс = Core Java SE 9 for the Impatient. —М.:«Вильямс», 2018. — 576 с. —ISBN 978-5-6040043-0-2, 978-0-13-469472-6.
  • Кей С. Хорстманн. Java SE 8. Вводный курс = Java SE 8 for the Really Impatient. —М.:«Вильямс», 2014. — 208 с. —ISBN 978-5-8459-1900-7.
  • Фрэд Лонг, Дхрув Мохиндра, Роберт С. Сикорд, Дин Ф. Сазерленд, Дэвид Свобода. Руководство для программиста на Java: 75 рекомендаций по написанию надёжных и защищённых программ = Java Coding Guidelines: 75 Recommendations for Reliable and Secure Programs. —М.:«Вильямс», 2014. — 256 с. —ISBN 978-5-8459-1897-0.
  • Кей С. Хорстманн. Java. Библиотека профессионала, том 1. Основы. 10-е издание = Core Java. Volume I - Fundamentals (Tenth Edition). —М.:«Вильямс», 2017. — 864 с. —ISBN 978-5-8459-2084-3.
  • Кей С. Хорстманн. Java. Библиотека профессионала, том 2. Расширенные средства программирования. 10-е издание = Core Java. Volume II - Advanced Feature (Tenth Edition). —М.:«Вильямс», 2017. — 976 с. —ISBN 978-5-9909445-0-3.
  • Барри Берд. Java 9 для чайников = Java For Dummies, 7th edition. —М.:«Диалектика», 2018. — 624 с. —ISBN 978-5-9500296-1-5, 978-1-119-23555-2.
  • Кишори Шаран. Java 9. Полный обзор нововведений = Java 9 Revealed. —М.:«ДМК Пресс», 2018. — 544 с. —ISBN 978-5-97060-575-2.
  • Джеймс Гослинг, Билл Джой, Гай Стил, Гилад Брача, Алекс Бакли. Язык программирования Java SE 8. Подробное описание, 5-е издание = The Java Language Specification, Java SE 8 Edition (5th Edition) (Java Series). —М.:«Вильямс», 2015. — 672 с. —ISBN 978-5-8459-1875-8.
  • Джошуа Блох. Java. Эффективное программирование = Effective Java. — 3-е. —М.:Диалектика, 2019. — 464 с. —ISBN 978-5-6041394-4-8.
  • Бенджамин Дж. Эванс, Джеймс Гоф, Крис Ньюленд. Java: оптимизация программ. Практические методы повышения производительности приложений в JVM. —М.:Диалектика, 2019. — 448 с. —ISBN 978-5-907114-84-5.
  • Монахов Вадим. Язык программирования Java и среда NetBeans. — 3-е изд. —СПб.:БХВ-Петербург, 2011. — 704 с. —ISBN 978-5-9775-0671-7.
  • Брюс Эккель. Философия Java = Thinking in Java. — 4-е изд. —СПб.:Питер, 2018. — 1168 с. —ISBN 978-5-496-01127-3.

Ссылки

[править |править код]
Перейти к шаблону «External links»
Ссылки на внешние ресурсы
Перейти к шаблону «Внешние ссылки» Перейти к элементу Викиданных
  В социальных сетях
Фото, видео и аудио
Тематические сайты
Словари и энциклопедии
В библиографических каталогах
Перейти к шаблону «Java»
Платформы
ТехнологииSun
Основные сторонние технологии
История
Свойства языка
Скриптовые языки
Конференции Java
Источник —https://ru.wikipedia.org/w/index.php?title=Java&oldid=151349200
Категории:
Скрытые категории: