Чем отличается «написание конкретной JRE для каждой платформы» для разработчиков Java и «написание компилятора C ++ для каждой платформы» для C ++?
Чем отличается «написание конкретной JRE для каждой платформы» для разработчиков Java и «написание компилятора C ++ для каждой платформы» для C ++?
Ответы:
Java компилируется один раз, когда-нибудь запускается C ++ - это когда-нибудь один раз скомпилировать.
«написание конкретной JRE для каждой платформы» - это не то, что вы делаете каждый раз. Портирование JRE на новую платформу - это то, что вам нужно сделать только один раз. Эта задача обычно выполняется основным сопровождающим / разработчиком программы и / или платформы. При принятии решения о том, кто и как будет переносить JRE, может влиять множество факторов. Помимо прочего, это зависит от лицензии, под которой она опубликована (я слышал, что Java - это Open Source, так что, думаю, кто-то может это сделать). Забавный анекдот, Стив Джобс много думал о том, что не хотел заботиться о портировании Java на Mac около года назад.
Дело не в том, как или кто портирует JRE, а в том, что после его портирования каждое Java-приложение теперь теоретически должно легко работать на новой машине. В этом смысле JRE формирует уровень абстракции, полностью скрывая машину, что позволяет легко переносить.
Однако реальность не всегда так хороша. Я не стану называть переносимость «мифом», но это правда, что она не так совершенна. Например, в Java есть пакет под названием, JNI
который позволяет отправлять собственные вызовы, обходя JRE, тем самым предотвращая идеальную бесперебойную переносимость, которую любители Java любят называть «Писать один раз, запускай везде».
Как упоминалось в комментариях, подход C ++ к переносимости отличается. С одной стороны, это скомпилированный язык, и эти двоичные файлы почти всегда зависят от платформы. Таким образом, исполняемые файлы c ++ никогда не будут переносимыми (в отличие от Java). С другой стороны, портирования компилятора иногда бывает достаточно. Сообщество обнаружило, что путем переноса компилятора, а также некоторых основных библиотек языка, исходные коды (а не двоичные файлы) могут быть переносимыми.
Тем не менее, C ++ широко используется в критически важных системах, таких как компиляторы, ядра, системы реального времени, встраиваемые системы ... В C ++ есть аспект «низкого уровня», который нельзя упускать из виду, говоря о переносимости.
Это не просто язык - это библиотеки.
И Java, и C ++ предоставляют кроссплатформенные библиотеки. Java предоставляет более богатый набор.
Разница в том, что Java будет работать на любой платформе без перекомпиляции. Наличие компилятора C ++ для каждой платформы совсем не одно и то же.
Все ответы, начинающиеся с «Разница в ...», или что-то очень похожее, в основном неверны (извините, но такова жизнь). Есть действительно два отдельных различия между ними.
Одна из них (о которой много говорилось) заключается в том, что скомпилированная Java-программа может (или, по меньшей мере, должна) работать на любой соответствующей реализации Java, поэтому даже после компиляции вы все равно можете перемещать Java-программу с одной платформы на другую без повторной компиляции. , C ++ (по крайней мере, обычно) требует повторной компиляции для каждой целевой платформы.
Другая заключается в том, что Java (по крайней мере, пытается) гарантировать, что вся правильно написанная Java будет переносимой. По крайней мере, теоретически, вы не должны быть в состоянии написать любой код, который не является переносимым.
C ++ позволяет вам делать довольно много вещей, которые не переносимы. Стандарт C ++ содержит «предупреждения» о многих вещах, которые не переносимы (например, сообщают вам, что вы получите поведение, определяемое реализацией, или поведение, не определенное), но он не обязательно пытается помешать вам сделать это вообще. , Например, если вы хотите написать операционную систему для оборудования, использующего шину PCI, вам, вероятно, понадобится чтение / запись памяти конфигурации PCI. Это, очевидно, не будет переносимым на системы без шины PCI, но если вы пишете операционную систему для оборудования с шиной PCI, это в значительной степени необходимо. C ++ позволяет это, хотя, очевидно, он не будет переносимым.
Вы неправильно поняли помещение. Java- программы очень переносимы, потому что JVM обеспечивает стандартное поведение, гарантирующее то же самое. Программы на C ++ имеют менее стандартизированную среду, более близкую к реальному аппаратному обеспечению, поэтому программа должна быть в состоянии обрабатывать различные специфичные для платформы детали, такие как размер типа int, выравнивание слов и т. Д. И т. Д. И т. Д.
Сама JVM не очень портативна. Это непростая задача - портировать высокопроизводительную JVM на другую платформу или архитектуру процессора.
Разница в том, что Java (это не аббревиатура) программы могут распространяться в форме, которая может быть запущена на любом компьютере с установленной JVM, но C ++ обычно распространяется либо как исходный код, который очень неудобен для пользователя, либо как группа разных бинарных файлов для разных платформ.
Одна из причин, по которой Java считается переносимой, заключается в том, что в ней есть конкретные правила оценки арифметических выражений и запрещается реализациям оценивать их любым другим способом, даже если для оценки их в соответствии с предписаниями требуется более медленный код, чем при их более точной оценке. мода.
Например, учитывая
long thing1(int x) {
return (x+1)-1L;
}
double thing2(int x, float y) {
return x/y;
}
Значения thing1(2147483647)
и thing2(1123456700,11234567.0f)
должны быть равны -2147483649L и 99.9999923706054688, соответственно, даже если арифметически правильные значения будут 2147483647L и 100.0, и хотя на некоторых платформах код для генерирования численно-неверных результатов будет медленнее, чем код для генерации правильных результаты (на некоторых 64-битных платформах для принудительного переноса после (x + 1) потребуется дополнительная инструкция, а на платформе 8x87 для округления до значения 1123456700 float
потребуется дополнительная инструкция по сравнению с простой загрузкой это непосредственно в регистр с расширенной точностью).
(int)
качестве первого примера в (x+1)
подвыражения в первом примере, на float
второй пример по x
параметру, но , очевидно , я не дизайну языка ,
Объем работы для вспомогательных инструментов действительно одинаков, разница кроется в другом. После того, как программа C ++ была скомпилирована для платформы, вы должны скомпилировать ее снова, если хотите использовать ее на другой платформе. Однако, когда Java-программа была скомпилирована, вы можете переместить ее на любую другую платформу со средой выполнения без необходимости перекомпиляции.
Отвечая на вопрос «Является ли переносимость мифом?» Вместо «Что лучше в переносимости, Java или C ++», я скажу, что частичная переносимость возможна, но полная переносимость - это миф.
То, что я настаиваю на написании, и это относится к этому вопросу, заключается в том, что разработчики больше не работают только с простыми языками программирования, а с полными средами программирования.
И эти структуры включают библиотеки, базы данных, графические интерфейсы.
Какой язык программирования или какая среда программирования более переносимая?
Ну, это зависит от того, что ваше приложение. пытается достичь.
Дело в том, что «вы» не пишете JRE, вы пишете код Java, который выполняется на любом JRE. «Вы» пишете код C ++, который может потребовать внесения вами изменений, прежде чем он скомпилируется на другой платформе.
Многие люди забывают или не принимают во внимание реальность Java, когда говорят, что «она на 100% портативна» или подобные фразы.
Практически во всех крупных корпорациях / отделе программного обеспечения в недавнем прошлом была как минимум одна самодельная реализация Java со связанной с ней JRE, и некоторые до сих пор ее поддерживают, например, у Microsoft, IBM и Apple была своя собственная версия Java, отражающая их собственные идеи и мысли о том, куда должна идти индустрия и такой язык.
Как это для "портативного"? JRE везде, где вы включаете.
И это без учета того, что делал Sun / Oracle.
Примером того, почему Java-код не очень далек от C и C ++ с точки зрения переносимости, являются графические интерфейсы и графические серверы, у Apple была нестандартная реализация структуры графического интерфейса для собственного JRE, в результате чего было много головные боли и двойная работа для тех, кто хотел создать / перенести GUI с использованием Java для компьютеров Apple, и они были в основном вынуждены иметь дело с Quartz (как это с точки зрения «рычагов» и языков высокого уровня?).
Иногда даже наиболее часто используемые слова не отражают того значения, которое обычно им дают люди, для меня термин «переносимость» в мире Java больше похож на «внешний вид» в общем смысле; в коммерческом и финансовом плане перспективы лучше для вас , если вы принимаете Java , а не на других языках (по крайней мере , в то время , когда Java родился) , потому что у вас есть много работы , уже проделанной на одной стороне (вы получите JRE на что - либо это можно считать «компьютером»), и ваша кодовая база, вероятно, будет переносимой, поскольку вам нужно меньше ресурсов для переноса вашей программы, вот и все, независимо от того, является ли указанный ресурс деньгами, время или трудовые ресурсы не имеют значения, это меньше порог по сравнению с другими технологиями, и это то, для чего Java, это снижает этот порог.
Конечно, это верно, если вы принимаете условия Java, что означает виртуальную машину со сборкой мусора, что означает, что она потребляет больше ресурсов по сравнению с родными языками, если вы действительно хотите выжать максимум из вашего ЦП или серверной фермы. не думайте, что вы можете принять Java, если у вас действительно мало ресурсов или ваша компания действительно мала.
Мне все еще нужно найти одно нетривиальное Java-приложение, которое содержит только 1 версию для каждой строки кода или функциональности (то есть без какой-либо платформы), и оно на 100% переносимо среди всех основных JRE.