Что такое переносимость? Как java более портативна, чем другие языки?

Интересно, как Java более переносима, чем C, С++ и .NET и любой другой язык. Я много раз читал о том, что Java переносится благодаря интерпретатору и JVM, но JVM просто скрывает архитектурные различия в оборудовании, не так ли? Нам по-прежнему нужны разные JVM для разных архитектур машин. Что мне здесь не хватает? Поэтому, если кто-то пишет слой абстракции для C для наиболее распространенных архитектур, пусть говорят CVM, то любая программа на C будет работать на тех архитектурах, когда будет установлен CVM, не так ли?

Что это за переносимость? Можно ли назвать .NET переносимым?

Ответ 1

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

Есть несколько вещей, которые влияют на это. Один - это сам язык. Спецификация языка Java обычно оставляет гораздо меньше "реализации". Например, "i = я ++" является undefined в C и С++, но имеет определенное значение в Java. Более практично, типы типа "int" имеют определенный размер в Java (например: int всегда 32 бит), тогда как в C и С++ размер варьируется в зависимости от платформы и компилятора. Только эти отличия не мешают вам писать переносимый код на C и С++, но вам нужно быть гораздо более прилежным.

Другими являются библиотеки. В Java есть куча стандартных библиотек, которых нет у C и С++. Например, потоковые, сетевые и графические библиотеки. Библиотеки такого рода существуют для C и С++, но они не являются частью стандарта, и соответствующие библиотеки могут широко варьироваться от платформы к платформе.

Наконец, существует целый вопрос о том, можно ли просто взять исполняемый файл и отбросить его на другой платформе и заставить его работать там. Обычно это работает с Java, предполагая наличие JVM для целевой платформы. (и есть JVM для многих/большинства платформ, о которых люди заботятся) Это, как правило, неверно с C и С++. Обычно вам потребуется, по крайней мере, перекомпиляция, и предполагается, что вы уже позаботились о предыдущих двух моментах.

Да, если для нескольких платформ существует "CVM", это сделает C и С++ более переносимыми - вроде. Вам все равно нужно написать свой код C переносимым образом (например: не предполагая ничего о размере int, кроме того, что говорит стандарт), или вы должны написать CVM (при условии, что он принял единообразное решение для все эти вещи на всех целевых платформах). Вам также необходимо отказаться от использования нестандартных библиотек (нет сетей, потоковой передачи или графического интерфейса) или записать в библиотеки CVM для этих целей. Итак, мы действительно не говорим о том, чтобы сделать C и С++ более переносимым, но специальным CVM-C/С++, который переносится.

Опять же, переносимость не является черным и белым. Даже с Java все еще могут быть несовместимые. Библиотеки GUI (особенно AWT) были печально известны тем, что они несовместимы с поведением, и все, что связано с потоками, может вести себя по-разному, если вы получаете неаккуратность. В общем, однако, гораздо проще взять нетривиальную Java-программу, написанную на одной платформе, и запустить ее на другой, чем она должна делать то же самое с программой, написанной на C или С++.

Ответ 2

Как уже говорили другие, переносимость - это несколько нечеткая концепция. С определенной точки зрения, C на самом деле больше переносимый, чем Java. C делает очень мало предположений о базовом оборудовании. Он даже не предполагает, что в байте 8 бит, или что отрицательные числа должны быть представлены с использованием двух дополнений. Теоретически, до тех пор, пока у вас есть машина на основе Von Neumann и компилятор, вы можете пойти с C.

Фактически, программа "Hello world" , написанная на C, будет работать на многих других платформах, чем программа "Hello world" , написанная на Java. Вероятно, вы могли бы получить ту же самую программу "hello world", которая работает на PDP-11 и iPhone.

Однако реальность такова, что большинство программ реального мира делают намного больше, чем вывод "Hello world" . Java имеет репутацию более переносимого, чем C, потому что на практике требуется гораздо больше усилий для переноса реальных программ на C на разные платформы, чем в реальных Java-программах.

Это связано с тем, что язык C - это ANSI-C, который является языком общего назначения с голыми костями. Он не поддерживает сетевое программирование, потоки или разработку графического интерфейса. Поэтому, как только вы пишете программу, которая включает в себя любую из этих вещей, вы должны отказаться от менее портативного расширения на C, например Win32 или POSIX или что-то еще.

Но с помощью Java инструменты сетевого программирования, потоковой передачи и GUI определяются языком и встроены в каждую реализацию VM.

Тем не менее, я думаю, что многие программисты также недооценивают прогресс современного C/С++ в отношении переносимости в наши дни. POSIX имеет большое значение для обеспечения кросс-платформенной потоковой передачи, а когда дело доходит до С++, Boost предоставляет сетевые и потоковые библиотеки, которые в основном такие же портативные, как и все на Java. Эти библиотеки имеют некоторые специфичные для платформы причуды, но также и Java.

По сути, Java опирается на каждую платформу, имеющую реализацию виртуальной машины, которая будет предсказуемым образом интерпретировать байтовый код, а C/С++ использует библиотеки, которые содержат код, специфичный для платформы, с использованием препроцессора (#ifdef s). Обе стратегии позволяют кросс-платформенную потоковую обработку, создание сетей и разработку графического интерфейса. Это просто, что Java добился более быстрого прогресса, чем C/С++, когда дело доходит до переносимости. Спецификация языка Java была связана с потоками, сетями и графическим интерфейсом почти с первого дня, тогда как сетевая библиотека Boost появилась только в 2005 году, и только в 2011 году с С++ 11 стандартная переносная потоковая обработка была включена в С++.

Ответ 3

Когда вы пишете программу Java, она запускается на всех платформах, для которых JVM написан для них - Windows, Linux, MacOS и т.д.

Если вы пишете программу на С++, вам придется ее компилировать специально для каждой платформы.

Теперь говорят, что девиз Java "писать один раз, бегать повсюду" - это миф. Это не совсем верно для настольных приложений, которым требуется взаимодействие со многими собственными ресурсами, но каждое приложение JavaEE можно запускать на любой платформе. В настоящее время я работаю над окнами, а другие коллеги работают над Linux - без каких-либо проблем.

(Еще одна вещь, связанная с переносимостью, - это JavaEE (корпоративная версия). Говорят, что приложения, написанные с использованием технологий JavaEE, выполняются на любом сертифицированном JavaEE сервере приложений. Однако это не так, по крайней мере, до JavaEE6. (см. здесь))

Ответ 4

Переносимость - это мера для того, чтобы заставить программу работать в другой среде, чем там, где она возникла.

Теперь вы можете обсуждать, является ли JVM для Linux другой средой, чем для Windows (я бы сказал, что да), но факт остается фактом: во многих случаях при работе с вами не хватает усилий, чтобы избежать нескольких ошибок.

CVM, о котором вы говорите, очень много, что пытаются предоставить библиотеки POSIX и библиотеки времени выполнения, однако существуют большие различия в реализации, которые затрудняют преодоление препятствий. Разумеется, в случае с Microsoft и Apple они, вероятно, намеренно так, чтобы разработчики не выпускали продукты на конкурирующих платформах.

На фронте .net, если вы можете придерживаться того, что предоставляет mono, с открытым исходным кодом .Net, вы будете пользоваться примерно такой же переносимостью, как Java, но поскольку моно значительно отстает от версий Windows, это не популярный выбор. Я не знаю, насколько это популярно для серверной разработки, где я могу себе представить, что это не проблема.

Ответ 5

Java переносима с точки зрения разработчика: код, написанный на Java, может быть выполнен в любой среде без необходимости перекомпиляции. C не переносится, поскольку во многих случаях он не только привязан к конкретной ОС, но также всегда привязан к конкретной аппаратной архитектуре после ее компиляции. То же самое верно для С++..Net более портативен, чем C/С++, поскольку он также полагается на виртуальную машину и поэтому не привязан к конкретной аппаратной архитектуре во время компиляции, но ограничен Windows-машинами (официально).

Вы правы, JVM является специфичным для платформы (это должно быть!), но когда вы говорите, что Java переносима, вы говорите об этом с точки зрения разработчика, а стандартные разработчики Java не пишут JVM, они используют это: -).

Изменить @Raze2Dust Чтобы решить свой вопрос. Да, можно. Фактически, вы можете сделать Java-платформу спецификой, написав компилятор, который будет генерировать машинный код, а не байт-код. Но, как показывают некоторые другие комментарии, зачем вы это делаете? Вам нужно будет создать интерпретатор, который сопоставляет скомпилированный код для операций таким же образом, как работает JVM. Таким образом, длинный и короткий из них, безусловно, вы определенно могли бы, но почему бы вам?

Ответ 6

Вы спрашиваете, можно ли написать "C VM". Не совсем. "Java" - это большой термин, используемый Sun для обозначения множества вещей, включая язык программирования и виртуальную машину. "C" - это просто язык программирования: до компилятора и ОС и процессора, чтобы определить, в каком формате должен быть результирующий двоичный файл.

C иногда говорят, что он переносимый, поскольку он не указывает время выполнения. Люди, которые написали ваш компилятор, смогли выбрать вещи, которые имеют смысл для этой платформы. Недостатком является то, что C достаточно низкоуровневый, а платформы по-разному достаточно, что для программ C очень хорошо работать на одной системе, а не на другой.

Если вы комбинируете язык C с определенным ABI, вы можете определить для него виртуальную машину, аналогичную JVM. Например, есть несколько таких вещей, например:

  • "Спецификация Intel Binary Compatibility Specification" является примером такого ABI (который почти никто не использует сегодня)
  • "Microsoft Windows" также может быть таким ABI (хотя и огромным и недосказанным), для которого Wine является одной виртуальной машиной, в которой запущены программы, написанные для нее.
  • "MS-DOS", для которого dosemu является одной VM
  • "Linux" является одним из самых популярных сегодня, чьи программы могут запускаться самим Linux, NetBSD, или FreeBSD
  • "PA-RISC", для которого HP Dynamo была JIT-подобной VM

Все эти виртуальные машины на самом деле являются реальной машиной - никто, AFAIK, никогда не делал виртуальную машину C, которая была чисто виртуальной. Это неудивительно, так как C был разработан для эффективного использования аппаратного обеспечения, поэтому вы могли бы также запустить его в одной системе. Как показал HP, вы все равно можете сделать JIT для более эффективного выполнения кода, даже на той же платформе.

Ответ 7

Java предоставляет три различные типы переносимости:

Переносимость исходного кода:. Данная Java-программа должна давать идентичные результаты независимо от основного процессора, операционной системы или компилятора Java.

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

Переносимость ОС /GUI:. Java решает эту проблему, предоставляя набор библиотечных функций (содержащихся в Java-поставляемых библиотеках, таких как awt, util и lang), которые говорят с воображаемой ОС и мнимыми GUI. Так же, как JVM представляет виртуальный процессор, библиотеки Java представляют собой виртуальную ОС/графический интерфейс. Каждая реализация Java предоставляет библиотеки, реализующие эту виртуальную ОС/графический интерфейс. Java-программы, которые используют эти библиотеки, для обеспечения необходимого функционального порта ОС и графического интерфейса довольно легко.

Смотрите ссылку

Ответ 8

Вам нужна JVM для разных архитектур, но, конечно, ваши Java-программы работают на этой JVM. Поэтому, когда у вас есть JVM для архитектуры, ваши Java-программы доступны для этой архитектуры.

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

Ответ 9

Идея заключается в том, что язык Java переносимый (или, точнее, скомпилированный байт-код переносимый). Вы правы, что для каждой виртуальной машины требуется конкретная реализация для данного профиля оборудования. Однако, как только это будет сделано, все java-байт-коды будут работать на этой платформе. Вы пишете java/байт-код один раз, и он запускается на любой JVM.

.NET очень похож, но с гораздо меньшим акцентом на принципе. CLR аналогичен JVM и имеет свой собственный байт-код. Моно существует на * nix, но вы правы, что он не является "официальным".

Ответ 10

Переносимость или как указано в Википедии, "Переносимость программного обеспечения" - это возможность повторного использования одного и того же программного обеспечения (кода) в нескольких средах (ОС). Java JVM - это JVM, который можно запускать на любых операционных системах, которые были разработаны для: Windows, Linux, Mac OS и т.д.

В .NET можно переносить свое программное обеспечение на разные платформы. Из Wikipedia:

Конструкция .NET Framework позволяет теоретически быть платформой агностик и, следовательно, кросс-платформенный совместимы. То есть, программа написана использовать фреймворк без изменений на любом типе системы для которых реализованы.

И поскольку Microsoft никогда не внедряла среду .NET вне Windows и не заметила, что .NET является агностикой платформы, Mono сделал возможным для запуска приложений .NET и компиляции кода для работы в Linux.

Для таких языков, как С++, Pascal и т.д., вам нужно будет перейти к каждой ОС и построить ее на этой платформе, чтобы запустить ее на этой платформе. EXE файл в Windows не совпадает с .so в linux (машинный код), поскольку оба используют разные библиотеки для разговора с ядром, и каждая ОС имеет свое собственное ядро.

Ответ 11

WORE - Write Once Run Everywhere

В действительности это ограничивается платформами с JVM, но это покрывает большинство платформ, на которые вы хотели бы развернуть. Это почти на полпути между интерпретируемым языком и скомпилированным языком, получающим выгоду от обоих.