Это сравнение Java и C ++, два выдающихся объектно-ориентированных языков программирования.
Различия между языками программирования C ++ и Java можно проследить до их наследия, поскольку они имеют разные цели дизайна.
C ++ был разработан для программирования систем и приложений (т.е. программирования инфраструктуры), расширяя процедурное программирование язык C, который был разработан для эффективного выполнения. В C в C ++ добавлена поддержка объектно-ориентированного программирования, обработки исключений, управления ресурсами на основе времени жизни (RAII ), общего программирования, метапрограммирование шаблонов и Стандартная библиотека C ++, которая включает общие контейнеры и алгоритмы (Стандартная библиотека шаблонов или STL), а также многие другие средства общего назначения.
Java - это универсальный, параллельный, объектно-ориентированный язык программирования на основе классов, который разработан для минимизации зависимостей реализации. Он полагается на виртуальную машину Java, чтобы быть защищенной и очень портативной. Он поставляется в комплекте с обширной библиотекой, предназначенной для обеспечения полной абстракции базовой платформы. Java - это объектно-ориентированный язык со статической типизацией, использующий синтаксис, аналогичный (но несовместимый с) C ++. Он включает систему документации под названием Javadoc.
. Различные цели в разработке C ++ и Java привели к разным принципам и компромиссам дизайна между языками. Различия заключаются в следующем:
C ++ | Java |
---|---|
Расширяет C с помощью объектно-ориентированного программирования и общего программирования. Наиболее правильно можно использовать код C. | Сильно зависит от синтаксиса C ++ / C. |
Совместим с исходным кодом C, за исключением нескольких угловых случаев. | Предоставляет собственный интерфейс Java и недавно Java Native Access как способ прямого вызова кода C / C ++. |
Напишите один раз, скомпилируйте где угодно (WOCA). | Пишите один раз, запускайте где угодно / везде (WORA / WORE). |
Позволяет процедурное программирование, функциональное программирование, объектно-ориентированное программирование, общее программирование и метапрограммирование шаблонов. Выступает за сочетание парадигм. | Разрешает процедурное программирование, функциональное программирование (начиная с Java 8) и общее программирование (начиная с Java 5), но настоятельно рекомендует объектно-ориентированное парадигма программирования. Включает поддержку создания языков сценариев. |
Выполняется как собственный исполняемый машинный код для целевого набора команд (ов). | Работает на виртуальной машине. |
Предоставляет типы объектов и имена типов. Допускает отражение через информацию о типе времени выполнения (RTTI). | Является отражающим, что позволяет метапрограммировать и генерировать динамический код во время выполнения. |
Имеет несколько стандартов двоичной совместимости (обычно Microsoft (для компилятора MSVC) и Itanium / GNU (почти для всех других компиляторов)). | Имеет один стандарт двоичной совместимости, кросс-платформенный для ОС и компилятора. |
Необязательная автоматическая проверка границ (например, метод at ()в контейнерах vectorи string). | Все операции должны проходить обязательную проверку всеми совместимыми дистрибутивами Java. HotSpot может убрать проверку границ. |
Собственная поддержка беззнаковой арифметики. | Нативная арифметика без знака не поддерживается. Java 8 меняет некоторые из этого, но аспекты неясны. |
Стандартизированные минимальные ограничения для всех числовых типов, но фактические размеры определяются реализацией. Стандартизированные типы доступны через стандартную библиотеку . | Стандартизированные пределы и размеры всех примитивных типов на всех платформах. |
Указатели, ссылки и передача по значению поддерживаются для всех типов (примитивных или определяемых пользователем). | Все типы (примитивные типы и ссылочные типы) всегда передаются по значению. |
Управление памятью можно выполнять вручную через new / delete , автоматически по области действия или интеллектуальным указателям. Поддерживает детерминированное разрушение объектов. Сборка мусора ABI стандартизирован в C ++ 11, хотя компиляторы не обязаны реализовывать сборку мусора. | Автоматическая сборка мусора. Поддерживает недетерминированный метод finalize (), использование которого не рекомендуется. |
Управление ресурсами может выполняться вручную или с помощью автоматического управления ресурсами на основе времени жизни (RAII ). | Управление ресурсами обычно должно выполняться вручную или автоматически с помощью финализаторов, хотя обычно это не рекомендуется. Имеет try-with-resources для автоматического управления ресурсами на основе области (начиная с версии 7). Это также можно сделать с помощью внутреннего API |
Поддерживает классы, структуры (типы пассивных структур данных (PDS)) и объединения и может размещать их в куче или стеке. | Классы размещены в куче . Java SE 6 оптимизируется с помощью escape-анализа для выделения некоторых объектов в стеке . |
Позволяет явно переопределять типы и некоторые неявные сужающие преобразования (для совместимости с C). | Жесткий типобезопасность, за исключением расширяющих преобразований. |
Стандартная библиотека C ++ была разработана с учетом ограниченного объема и функций, но включает поддержку языка, диагностику, общие утилиты, строки, языковые стандарты, контейнеры, алгоритмы, итераторы, числа, ввод / вывод, генераторы случайных чисел, синтаксический анализ регулярных выражений, средства многопоточности, характеристики типов (для самоанализа статических типов) и стандартная библиотека C. Библиотека Boost предлагает больше функций, включая сетевой ввод-вывод. Существует большое количество сторонних библиотек для графического интерфейса пользователя и других функций, таких как: Adaptive Communication Environment (ACE), Crypto ++, различные XMPP Библиотеки мгновенного обмена сообщениями (IM), OpenLDAP, Qt, gtkmm. | Стандартная библиотека расширяется с каждым выпуском. К версии 1.6 библиотека включала поддержку локалей, журналов, контейнеров и итераторов, алгоритмов, программирования графического интерфейса (но без использования системного графического интерфейса), графики, многопоточности, сети, безопасности платформы, самоанализа, загрузки динамических классов, блокировки и отсутствия -блокировка ввода / вывода. Он предоставил интерфейсы или классы поддержки для XML, XSLT, MIDI, подключения к базе данных, служб именования (например, LDAP ), криптографии, безопасности службы (например, Kerberos ), службы печати и веб-службы. SWT предлагал абстракцию для графических интерфейсов, зависящих от платформы, но в последних версиях был заменен на JavaFX ; возможность ускорения графики и пользовательских интерфейсов с поддержкой CSS. Хотя он не поддерживает какую-либо поддержку «родного вида платформы». |
Перегрузка оператора для большинства операторов. Настоятельно рекомендуется сохранять значение (семантику). | Операторы не могут быть изменены. Язык отменяет + и + = для класса String. |
Одиночное и множественное наследование классов, включая виртуальное наследование. | Поддерживает только одиночное наследование классов. |
Шаблоны времени компиляции. Позволяет завершить метапрограммирование по Тьюрингу. | Generics используются для достижения базовой параметризации типа, но они не преобразуются из исходного кода в байтовый код из-за использования компилятором стирания типа. |
Указатели на функции, объекты функций, лямбда-выражения (в C ++ 11 ) и интерфейсы. | Ссылки на функции, объекты функций и лямбда-выражения были добавлены в Java 8. Классы (и интерфейсы, которые являются классами) также могут передаваться как ссылки через SomeClass.class |
Отсутствует стандартный механизм встроенной документации. Существует стороннее программное обеспечение (например, Doxygen ). | Обширный стандарт документации Javadoc для всех системных классов и методов. |
const ключевое слово для определения неизменяемых переменных и функций-членов, которые не изменяют объект. Постоянство распространяется как средство обеспечения во время компиляции правильности кода в отношении изменчивости объектов (см. const-correction ). | final предоставляет версию const , эквивалентную указателям type * const для объектов и const для примитивных типов. Неизменяемость членов объекта достигается с помощью интерфейсов только для чтения иинкапсуляции объектов. |
Поддерживает оператор goto . | Поддерживает метки с циклами и блоками операторов. goto - зарезервированное ключевое слово, но помечено как "неиспользуемое" в спецификации Java. |
Исходный код может быть записан как кроссплатформенный (может быть скомпилирован для Windows, BSD, Linux, macOS, Solaris и т. Д., Без изменений) и написаны для использования особенности платформы. Обычно компилируется в машинный код, его необходимо перекомпилировать для каждой целевой платформы. | Скомпилировано в байт-код Java для JVM. Байт-код зависит от платформы Java, но обычно не зависит от конкретных функций операционной системы. |
Foo <1>(3);
- это последовательность сравнений, если Foo является переменной, но создает объект, если Foo является именем шаблона класса.C ++ | Java |
---|---|
class Foo {// Объявляет class Foo int x = 0; // Переменная частного члена. Он будет // инициализирован в 0, если // конструктор не установил его. // (из C ++ 11) public: Foo (): x (0) // Конструктор для Foo; инициализирует {} // x значением 0. Если бы инициализатор был // опущен, переменная // была бы инициализирована значением, которое // было присвоено при объявлении x. int bar (int i) {// Функция-член bar () return 3 * i + x; }}; | class Foo {// Определяет class Foo private int x; // Переменная-член, обычно объявленная // как закрытая для принудительной инкапсуляции // инициализированная 0 по умолчанию public Foo () {// Конструктор для Foo} // конструктор без аргументов, предоставленный по умолчанию public int bar (int i) {/ / Элемент метода bar () return 3 * i + x; }} |
Foo a; // объявляет, что a является значением объекта Foo, // инициализируемым с помощью конструктора по умолчанию. // Другой конструктор можно использовать как Foo a (args); // или (C ++ 11): Foo a {args}; | Foo a = новый Foo (); // объявляет, что a является ссылкой на новый объект Foo, // инициализированный с помощью конструктора по умолчанию // Другой конструктор может использоваться как Foo a = new Foo (args); |
Foo b = a; // копирует содержимое a в новый объект Foo b; // альтернативный синтаксис: «Foo b (a)» | // Foo b = a; // объявил бы b ссылкой на объект, на который указывает Foo b = a.clone (); // копирует содержимое объекта, на который указывает //, в новый объект Foo; // устанавливает ссылку b, указывающую на этот новый объект; // класс Foo должен реализовать интерфейс Cloneable // для компиляции этого кода |
a.x = 5; // изменяет объект a | a.x = 5; // изменяет объект, на который ссылается |
std :: cout << b.x << std::endl; // outputs 0, because b is // some object other than a | System.out.println (b.x); // выводит 0, потому что b указывает // на какой-то объект, отличный от a |
Foo * c; // объявляет c как указатель на // объект Foo (изначально // не определено; может указывать куда угодно) | Foo c; // объявляет c как ссылку на объект Foo // (изначально null, если c является членом класса; // необходимо инициализировать c перед использованием // если это локальная переменная) |
c = new Foo ; // c устанавливается в значение адреса объекта Foo, созданного оператором new | c = new Foo (); // связывает c для ссылки на новый объект Foo |
Foo d = * c; // связывает d для ссылки на тот же объект, на который указывает c | Foo d = c; // связывает d для ссылки на тот же объект, что и c |
c->x = 5; // изменяет объект, на который указывает c | c.x = 5; // изменяет объект, на который ссылается c |
d.bar (5); // вызывает Foo :: bar () для c->bar (5); // вызывает Foo :: bar () для * c | d.bar (5); // вызывает Foo.bar () для c.bar (5); // вызывает Foo.bar () для c |
std :: cout << d.x << std::endl; // outputs 5, because d references the // same object to which c points | System.out.println (d.x); // выводит 5, потому что d ссылается на // тот же объект, что и c |
final
.C ++ | Java |
---|---|
const Foo * a; // невозможно изменить объект, // на который указывает a через Foo * const a = new Foo; // Объявление константного указателя: // объект можно изменить, // но указатель будет постоянно указывать // на назначенный ему здесь объект | final Foo a; // объявление "окончательной" ссылки: // объект можно изменить, // но ссылка будет постоянно указывать // на первый назначенный ему объект |
a = new Foo (); | a = новый Foo (); // Только в конструкторе |
a->x = 5; // НЕЗАКОННЫЙ | a.x = 5; // ЛЕГАЛЬНО, члены объекта все еще могут быть изменены // если явно не объявлено final в объявляющем классе |
Foo * const b = new Foo (); // объявление "константного" указателя | final Foo b = new Foo (); // объявление «последней» ссылки |
b = new Foo (); // НЕЗАКОННО, его нельзя повторно привязать | b = new Foo (); // НЕЗАКОННО, перепривязать нельзя |
b->x = 5; // ЮРИДИЧЕСКИЙ, объект все еще можно изменить | b.x = 5; // ЮРИДИЧЕСКИЙ, объект все еще может быть изменен |
goto
, что может привести к программированию спагетти-кода. За исключением оператора goto (который очень редко встречается в реальном коде и крайне не рекомендуется), как Java, так и C ++ имеют в основном одинаковые структуры потока управления , разработан для обеспечения выполнения структурированного потока управления и использует операторы break и continue для предоставления некоторых функций, подобных goto
. Некоторые комментаторы отмечают, что эти помеченные операторы управления потоком нарушают свойство единой точки выхода структурного программирования.if
, while
и условие выхода в для
) в Java и C ++ оба ожидают логического выражения, код, такой как if (a = 5)
вызовет ошибку компиляции в Java, потому что не существует неявного сужающего преобразования из int в логическое значение, но будет компилироваться на C ++. Это удобно, если код был опечаткой и , если (a == 5)
был предназначен. Однако современные компиляторы C ++ обычно генерируют предупреждение, когда такое присвоение выполняется в условном выражении. Аналогично, автономные сравнительные операторы, например a == 5;
, без побочного эффекта обычно приводит к предупреждению.new
и оставлены без удаления), оно обеспечивает эффективное средство управления ресурсами. Общими ресурсами можно управлять с помощью shared_ptr
вместе с weak_ptr
для разрыва циклических ссылок. Java поддерживает автоматическое управление памятью с использованием сборки мусора, которая может освобождать недоступные объекты даже при наличии циклических ссылок, но другие системные ресурсы (файлы, потоки, окна, порты связи, потоки и т. Д.) Должны быть явно освобождены поскольку сборка мусора не гарантируется сразу после отказа от последней ссылки на объект.synchronized
в Java обеспечивает простые и безопасные блокировки мьютекса для поддержки многопоточных приложений. Java также предоставляет надежные и сложные библиотеки для более продвинутой многопоточной синхронизации. Только с C ++ 11 существует определенная модель памяти для многопоточности в C ++ и поддержка библиотек для создания потоков и многих синхронизирующих примитивов. Для этого также существует множество сторонних библиотек.final
(т.е. виртуального отказа).общедоступным статическим перечислением {enumName1, enumName2}
и используются как классы. Другой способ - создать другой класс, который расширяет java.lang.Enum
) и поэтому может определять конструкторы, поля и методы, как любой другой класс. Начиная с C ++ 11, C ++ также поддерживает строго типизированные перечисления, которые обеспечивают большую безопасность типов и явную спецификацию типа хранилища.C ++ | Java |
---|---|
C ++ компилируется непосредственно в машинный код , который затем выполняется непосредственно центральным процессором. | Java компилируется в байт-код, который виртуальная машина Java (JVM) затем интерпретирует во время выполнения. Фактические реализации Java выполняют своевременную компиляцию собственного машинного кода. В качестве альтернативы компилятор GNU для Java может компилироваться непосредственно в машинный код. |
Оба C ++ и Java предоставляют средства для универсального программирования, шаблонов и универсальных шаблонов соответственно. Хотя они были созданы для решения аналогичных задач и имеют похожий синтаксис, они совершенно разные.
Шаблоны C ++ | Универсальные шаблоны Java |
---|---|
Можно создавать шаблоны для классов, функций, псевдонимов и переменных. | Классы и методы могут быть универсальными. |
Параметры могут быть вариативными, любого типа, целочисленного значения, символьного литерала или шаблона класса. | Параметры могут быть любого ссылочного типа, включая примитивные типы в штучной упаковке (например, Integer, Boolean...). |
При компиляции для каждого набора параметров будут созданы отдельные экземпляры класса или функции. Для шаблонов классов будут созданы экземпляры только используемых функций-членов. | Компилируется одна версия класса или функции, работает для всех параметров типа (через стирание типа). |
Объекты шаблона класса, экземпляры которого созданы с разными параметрами, будут иметь разные типы во время выполнения (т. Е. Отдельные экземпляры шаблона являются отдельными классами). | Параметры типа стираются при компиляции; объекты класса с разными параметрами типа являются одним и тем же типом во время выполнения. Это вызывает другой конструктор. Из-за стирания этого типа невозможно перегрузить методы, используя различные экземпляры универсального класса. |
Реализация шаблона класса или функции должна быть видна в единице перевода, чтобы ее можно было использовать. Обычно это подразумевает наличие определений в файлах заголовков или включение в файл заголовков. Начиная с C ++ 11, можно использовать шаблоны extern для разделения компиляции некоторых экземпляров. | Для использования достаточно сигнатуры класса или функции из скомпилированного файла класса. |
Шаблоны могут быть специализированными - для отдельного параметра шаблона может быть предусмотрена отдельная реализация. | Универсальные шаблоны нельзя специализировать. |
Параметры шаблона могут иметь аргументы по умолчанию. До C ++ 11 это было разрешено только для классов шаблонов, но не для функций. | Параметры универсального типа не могут иметь аргументы по умолчанию. |
Подстановочные знаки не поддерживаются. Вместо этого возвращаемые типы часто доступны как вложенные typedef. (Кроме того, в C ++ 11 добавлено ключевое слово auto , которое действует как подстановочный знак для любого типа, который может быть определен во время компиляции.) | Подстановочные знаки поддерживаются как тип параметр. |
Нет прямой поддержки ограничения параметров типа, но это обеспечивает метапрограммирование. | Поддерживает ограничение параметров типа с помощью "extends" и "super" для верхней и нижней границ соответственно; позволяет устанавливать отношения между параметрами типа. |
Разрешает создание экземпляра объекта с типом типа параметра. | Исключает создание экземпляра объекта с типом типа параметра (кроме как через отражение). |
Параметр типа шаблона класса может использоваться для статических методов и переменных. | Параметр типа универсального класса нельзя использовать для статических методов и переменных. |
Статические переменные не используются совместно классами и функциями с параметрами разных типов. | Статические переменные, совместно используемые экземплярами классов с параметрами разных типов. |
Шаблоны классов и функций не устанавливают отношения типов для параметров типа в своем объявлении. Использование неверного параметра типа приводит к сбою компиляции, часто генерируя сообщение об ошибке в коде шаблона, а не в коде пользователя, который его вызывает. Правильное использование шаблонных классов и функций зависит от надлежащей документации. Метапрограммирование предоставляет эти функции за счет дополнительных усилий. Было предложение решить эту проблему в C ++ 11, так называемые Concepts, это планируется в следующем стандарте. | Универсальные классы и функции могут устанавливать отношения типов для параметров типа в своем объявлении. Использование неверного параметра типа приводит к ошибке типа в коде, который его использует. Операции с параметризованными типами в универсальном коде разрешены только способами, безопасность которых может быть гарантирована объявлением. Это приводит к большей безопасности типов за счет гибкости. |
Шаблоны - это полные по Тьюрингу (см. метапрограммирование шаблонов ). | Обобщения также являются полными по Тьюрингу |
(a / b) * b + (a% b) == a
для всех a и b (b! = 0). Версия C ++ 03 иногда будет быстрее, так как можно выбрать любой режим усечения, свойственный процессору.Пример сравнения C ++ и Java существует в Wikibooks.
В дополнение к запуску скомпилированной программы Java на компьютерах, на которых выполняются приложения Java, обычно также должна быть запущена виртуальная машина Java (JVM), а скомпилированные программы на C ++ могут запускаться без внешних приложений. Ранние версии Java значительно уступали по производительности статически компилируемым языкам, таким как C ++. Это связано с тем, что операторы программ этих двух тесно связанных языков могут компилироваться в несколько машинных инструкций с помощью C ++, в то же время компилируясь в несколько байтовых кодов, включающих несколько машинных инструкций, каждая при интерпретации JVM. Например:
инструкция Java / C ++ | сгенерированный код C ++ (x86) | сгенерированный Java байт-код |
---|---|---|
vector [i] ++; | mov edx, [ebp + 4h] mov eax, [ebp + 1Ch] inc dword ptr [edx + eax * 4] | aload_1 iload_2 dup2 iaload iconst_1 iadd iastore |
Поскольку оптимизация производительности - очень сложная проблема, очень трудно количественно оценить разница в производительности между C ++ и Java в целом, и большинство тестов ненадежны и необъективны. Учитывая очень разную природу языков, также трудно провести четкие качественные различия. Короче говоря, в Java есть неотъемлемая неэффективность и жесткие ограничения, поскольку она в значительной степени полагается на гибкие высокоуровневые абстракции, однако использование мощного JIT-компилятора (как в современных реализациях JVM) может смягчить некоторые проблемы. В любом случае, если неэффективность Java слишком велика, скомпилированный код C или C ++ может быть вызван из Java через JNI.
Некоторые недостатки, присущие языку Java, включают, в основном:
sun.misc.Unsafe
для получения доступа к ручному управлению ресурсами и возможности выделения стека; эффективное управление псевдо-указателями.Тем не менее, у дизайна Java есть ряд преимуществ, некоторые из которых были реализованы, некоторые - только теоретически:
Кроме того, в C ++ возникают некоторые проблемы с производительностью:
Язык C ++ определен ISO / IEC 14882, стандартом ISO, который опубликован комитетом ISO / IEC JTC1 / SC22 / WG21. Также доступен последний постстандартизационный черновик C ++ 17.
Язык C ++ развивается через открытый руководящий комитет, называемый Комитетом по стандартам C ++. Комитет состоит из создателя C ++ Бьярна Страуструпа, организатора Херба Саттера и других видных деятелей, включая многих представителей отраслей и групп пользователей (т. Е. Заинтересованных сторон).). Поскольку комитет является открытым, любой может свободно присоединяться к нему, участвовать и вносить предложения по предстоящим выпускам стандарта и технических спецификаций. В настоящее время комитет стремится выпускать новый стандарт каждые несколько лет, хотя в прошлом строгие процессы проверки и обсуждения означали более длительные задержки между публикацией новых стандартов (1998, 2003 и 2011).
Язык Java определяется Спецификацией языка