Чому Java вважається більш портативною, ніж інші мови на зразок C ++?


16

Що відрізняється між "написанням конкретного JRE для кожної платформи" для розробників Java та "написанням компілятора C ++ для кожної платформи" для C ++?

Відповіді:


33

Java компілюється після запуску в будь-якому місці. C ++ - це написання одного разу компіляція в будь-якому місці.


3
Ну, ви, очевидно, не мали великого досвіду розробки графічного інтерфейсу. (Чекаю Qt ...)

27
Кожному, хто стверджує, що C ++ є "написати один раз компілювати куди завгодно", ніколи не довелося переносити програму C ++ ...
BlueRaja - Danny Pflughoeft

7
Я погоджуюся з BlueRaja. Перенесення програми на C ++ означає набагато більше, ніж перенесення компілятора. C ++ найбільш широко присутній у критичних середовищах, де такі речі, як розмір int або реалізація файлової системи, можуть настільки сильно змінитись. Перенесення НЕ означає просто перекомпіляцію.
rahmu

8
@ Pubby8 ні, проблеми з портативністю також випливають із досить стандартного коду, який робить нерозмірні припущення , як припущення про витривалість (які ви пам’ятаєте, ви також можете страждати від Java), вирівнювання та розмір основних типів.
Р. Мартіньо Фернандес

5
Пишіть один раз, налагоджуйте всюди.
bhagyas

25

"написання конкретного JRE для кожної платформи" - це не те, що ви робите кожен раз. Перенесення JRE на нову платформу - це те, що вам потрібно зробити лише один раз. Це завдання, як правило, виконується основним обслуговувачем / розробниками програми та / або платформи. Дуже багато факторів можуть зігратись при вирішенні питання про те, хто і як буде переноситися JRE. Крім усього іншого, це залежить від ліцензованої версії, опублікованої під ним (я чую, що Java є відкритим кодом, тому, мабуть, хтось міг би це зробити). Смішний анекдот, Стів Джобс зробив велику справу про те, що не хотів піклуватися про перенесення Java на Mac близько року тому.

Справа не в тому, як або хто портує JRE, а в тому, що колись він переноситься, кожен додаток Java тепер теоретично повинен легко працювати на новій машині. У цьому сенсі JRE утворює шар абстракції, повністю приховуючи машину, дозволяючи легко переносити.

Однак реальність не завжди така, як така. Я не піду, як називати портативність "міфом", але це правда, що це не так ідеально. Наприклад, у Java є пакет, який називається, JNIякий дозволяє надсилати натільні дзвінки, обходячи JRE, таким чином запобігаючи ідеальну безперебійну переносимість, як любителі Java називати "Пишіть, як тільки запустіть всюди".

Як зазначалося в коментарях, підхід C ++ до портативності відрізняється. З одного боку, це компільована мова, і ці двійкові файли майже завжди є специфічними для платформи. Тож виконувані файли c ++ ніколи не будуть портативними (на відміну від Java). З іншого боку, перенесення компілятора іноді може бути достатньо. Спільнота виявила, що, перенісши компілятор, а також деякі основні бібліотеки мови, вихідні коди (а не бінарні файли) можуть бути переносними.

Однак C ++ широко використовується в таких критичних системах, як компілятори, ядра, системи в режимі реального часу, вбудовані системи ... Існує "низький рівень" аспекту C ++, який неможливо не помітити, якщо говорити про портативність.


4
Переносність - це не міф. Ідеальна портативність.
Малькольм

"його - це те, де Java сильно відрізняється від C ++, де кожен додаток є" специфічним для машини ", і його неможливо перенести без зміни коду." Це неправда, це залежить від залежностей. Якщо ви використовуєте лише стандартну бібліотеку та бібліотеки з джерелами, які переносяться на цілі, ви кодуєте один раз і компілюєте кожну ціль. Якщо ви кодуєте щось, що можна перенести без зміни коду в C ++, єдине, що вам може знадобитися змінити - це сценарії збірки. Це навіть не так у всіх випадках.
Клайм

Не будемо забувати, що C ++ можна використовувати як як на високому, так і на низькому рівні. Багато програм C ++ використовується в програмах, де 32-бітний інт сильно відрізняється від 64-розрядного int. Звичайно, високий рівень завжди буде портативним. Але це далеко не узагальнення C ++
rahmu

Я думаю, що ви могли неправильно зрозуміти, про що я говорю: ви можете писати правильний C ++ за допомогою int або будь-якого стандартного типу, не турбуючись з низькорівневими речами. Просто подивіться на збільшені бібліотеки, більшість - це лише код високого рівня, і це справедливо для багатьох проектів з відкритим кодом C ++. Ви можете "знизити" низький рівень, і якщо це зробити, ви також можете уникнути будь-якого конкретного коду, поки вам не потрібно використовувати конкретний API для платформи. Але якщо вам цього не потрібно, ви можете написати C ++, який працює скрізь. Залежність від платформи можна уникнути і часто є в коді бібліотеки.
Клайм

Щоб бути впевненим, я зрозумів: я не кажу, що весь код C ++ є портативним, я кажу, що так, як і ваше твердження, неправильне. Ви можете виправити це на кшталт: "Тут Java сильно відрізняється від C ++, де кожна програма" специфічна для машини ", і її неможливо перенести без зміни коду або, якщо код справді портативний, і збірка сценарії керують новою ціллю, не маючи принаймні однієї компіляції. "
Клайм

14

Це не лише мова - це бібліотеки.

І Java, і C ++ забезпечують бібліотеки між платформами. Java забезпечує більш багатий набір.


2
Java за замовчуванням надає більш багатий набір. Ті ж бібліотеки можна знайти для C ++, вони просто не входять до стандартних бібліотек, і вам просто потрібно вирішити, які з них використовувати (що не тривіально, особливо якщо вони не встановлені).
Мартін Йорк

Порівняння стандартних бібліотек Java з всесвітом бібліотек для C ++ насправді не є коректним порівнянням. Java надає більш багатий набір, чи порівнюєте ви стандартні бібліотеки кожної, чи ви порівнюєте всесвіт бібліотек кожної.
Енді Томас

3
Однозначно з цим не згоден. Все, що є в бібліотеці Java, уже доступне для використання C ++ у деякій бібліотеці. Мені подобається те, що у Java це все в одному місці, але говорити, що вона багатша, просто неправда. Можливо, прикметник, який ви шукаєте, є "більш інтегрованим"
Martin York

1
+1 знову підтвердить голос. Я думаю, що бібліотеки є найбільшим фактором портативності. Якщо ви працюєте в C / C ++ і робите що-небудь, крім чистого обчислення, то існують бібліотеки (зокрема, частини системної бібліотеки), які кардинально відрізняються між Windows та Unix і дещо відрізняються між різними смаками Unix. Це робить перенос важким. У Java в основному немає такої проблеми.
Том Андерсон

1
@Andy Thomas-Cramer: Я нічого не порівнюю (ви, здається, є). Я кажу, що ваше твердження є неточним. Однією з переваг, які має Java (і ми всі її любимо за це), є всі стандартні бібліотеки в одному місці. Сказати, що вони багатші, просто не точно.
Мартін Йорк

7

Різниця полягає в тому, що Java працюватиме на будь-якій платформі без перекомпіляції. Наявність компілятора C ++ для кожної платформи зовсім не однакова.


6

Усі відповіді, що починаються з "Різниця - це ...", або що-небудь дуже схоже, в основному неправильні (вибачте, але таке життя). Дійсно є дві окремі відмінності між ними.

Одне (про що було сказано багато) полягає в тому, що складена програма Java може (або, щонайменше, повинна) працювати на будь-якій відповідній реалізації Java, тому навіть після її складання ви все одно можете переміщати програму Java з однієї платформи на іншу без повторного компіляції. . C ++ (принаймні зазвичай) вимагає перекомпіляції для кожної цільової платформи.

Інша полягає в тому, що Java (принаймні, намагається) запевнити, що всі правильно написані Java будуть портативними. Принаймні теоретично, ви не повинні мати можливість писати будь-який код, який не є портативним.

C ++ дозволяє робити дуже багато речей, які не є портативними. Стандарт C ++ містить "попередження" про багато речей, які не є портативними (наприклад, говорять про те, що ви отримаєте певну реалізацію поведінку або невизначену поведінку), але це не обов'язково намагатися взагалі не заважати вам робити їх. . Наприклад, якщо ви хочете написати операційну систему для обладнання, яке використовує шину PCI, вам, ймовірно, потрібно буде прочитати / записати пам'ять конфігурації PCI. Це, очевидно, не може бути портативним для систем без шини PCI, але якщо ви пишете операційну систему для апаратного забезпечення з шиною PCI, це дуже необхідно. C ++ дозволяє це, хоча він, очевидно, не буде портативним.


C ++ нічого не знає ні про шину PCI, ні про апаратне забезпечення.
Нікко

Звичайно, це не так, це конкретні платформні речі, які доведеться включати в певні бібліотеки платформи. Так само, як Java може мати бібліотеки для певної платформи, якщо це потрібно.
jwenting

1
@Nikko: Він нічого про це не знає, але дозволяє використовувати те, що ви знаєте про нього.
Джеррі Труну

@jwenting: Різниця полягає в тому, що ви можете писати спеціалізовані для платформи бібліотеки на C ++, але ви, як правило, не можете їх записувати на Java.
Джеррі Труну

6

Ви неправильно зрозуміли приміщення. Програми Java дуже портативні, оскільки JVM забезпечує стандартну поведінку, гарантовано однакову. Програми C ++ мають менш стандартизоване середовище, наближене до фактичного обладнання, тому програма повинна вміти обробляти різні деталі платформи - наприклад, розмір int, вирівнювання слів тощо тощо тощо.

Сам JVM не дуже портативний. Перенести високоефективний JVM на іншу платформу або архітектуру процесора - це геркулесова задача.


+1 за останнє речення!
рахму

2

Різниця полягає в тому, що програми Java (це не абревіатура) можуть бути розповсюджені у формі, яку можна запустити на будь-якому комп’ютері зі встановленим JVM, але C ++ зазвичай розповсюджується як вихідний код, який дуже непривітний для користувачів, або як купа різних бінарних файлів для різних платформ.


Так? Є компілятори C ++, націлені на JVM, і є компілятори Java, які орієнтують на власний код. Чи можете ви навести конкретний розділ специфікації мови C ++, який говорить про те, що програми C ++ повинні бути розповсюджені у вигляді вихідного коду або бінарних файлів, орієнтованих на платформу?
Jörg W Mittag

Там я відредагував свою відповідь, щоб використовувати менш остаточну мову
Колін

2

Однією з причин, яку 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знадобиться додаткова інструкція порівняно з просто завантаженням безпосередньо в регістр розширеної точності).


1
Одного разу нова відповідь на старе питання, яка насправді додає щось цінне: Java має дуже точні арифметичні вимоги, і, звичайно, примітивні типи даних мають конкретні розміри та семантику порівняно з C ++. На цю дату жодна інша відповідь не згадує.

@Snowman: Як вам подобаються обрані конкретні приклади? Особисто, якби я розробляв мову, я б не зробив жодного прикладу повернення значення Java без використання звужуючих літрів до підсупресії (int)першого прикладу (x+1)в першому прикладі до floatпараметра другого прикладу x, але явно я не створив мову .
supercat

Я думаю, що вони мають сенс. Для будь-якої мови важливо мати чітко виражену семантику. Незалежно від того, чи погоджуєтесь ви з певним мовним дизайнерським рішенням, важливим є вміння подивитися на код і знати, як він працює. Як правило, Java це робить, не маючи випадків невизначеної поведінки.

1

Обсяг роботи для опорних інструментів дійсно схожий, різниця полягає в іншому. Після того, як програма C ++ була скомпільована для платформи, її потрібно скомпілювати ще раз, якщо ви хочете використовувати її на іншій платформі. Однак, коли програма java складена, ви можете перемістити її на будь-яку іншу платформу із середовищем виконання, не потребуючи її перекомпіляції.


1

Відповідаючи на заголовок "Чи портативність є міфом?", Замість "Що краще в портативності, Java або C ++", я скажу, що часткова портативність можлива, але повна портативність - це міф.

Я наполягаю на тому, що я наполягаю, і це стосується цього питання, це те, що розробники вже не працюють лише з простою мовою програмування, але з повноцінними рамками програмування.

І ці рамки включають бібліотеки, бази даних, графічні інтерфейси.

Яка мова програмування або яка програма програмування є більш портативною?

Ну, це залежить від того, який у вас додаток. намагається досягти.


1

Річ у тому, що "ти" не пишеш JRE, ти пишеш код Java, який працює на будь-якому JRE. «Ви» писати код C ++ , які можуть вимагати зміни від вас , перш ніж він буде компілювати на іншій платформі.


0

Багато людей забувають або не беруть до уваги реальність Java, коли кажуть, що "це 100% портативний" або фрази на зразок цього.

Насправді всі основні корпорації / програмний дім мали принаймні 1 домашню реалізацію Java з пов'язаним з нею JRE у недавньому минулому, а деякі досі підтримують її, наприклад, Microsoft, IBM і Apple, наприклад, всі мали власну версію Java, що відображає їх власні ідеї та думки про те, куди має йти галузь та така мова.

Як це для "портативних"? JRE де завгодно.

І це не зважаючи на те, що робило Sun / Oracle.

Прикладом того, чому Java-код не дуже далекий від C та C ++ з точки зору переносимості, - це графічні інтерфейси та графічні сервери, Apple мала нестандартну реалізацію рамки GUI для власного JRE, як наслідок, було багато головні болі та подвійна робота для всіх, хто хотів створити / поставити графічний інтерфейс, використовуючи Java для машин Apple, і в основному вони були змушені мати справу з Quartz (як це з точки зору "важелів" та мов високого рівня?).

Іноді навіть найпоширеніші слова, що вживаються, насправді не відображають значення, яке люди зазвичай їм надають, для мене термін «переносимість» у світі Java більше схожий на «світогляд» у здоровому розумінні; у комерційному та фінансовому плані для вас є кращий прогноз, якщо ви перейдете на Java, а не на інші мови (принаймні на той час, коли народилася Java), оскільки у вас вже багато роботи зроблено з одного боку (ви отримуєте JRE на будь-що що можна вважати "комп'ютером"), і ваша кодова база, швидше за все, буде портативною, як є, вам потрібно менше ресурсів для порту вашої програми, це все, чи не вказаний ресурс - це гроші, час або робоча сила не має значення, це нижча Поріг порівняно з іншими технологіями, і для чого саме Java, вона знижує цей поріг.

Звичайно, це справедливо, якщо ви приймаєте приміщення Java, що означає віртуальну машину зі збиранням сміття, а це означає, що вона витрачає більше ресурсів, якщо порівнювати з рідними мовами, якщо ви дійсно хочете вичавити максимум із вашого центрального процесора або серверної ферми I не думайте, що ви можете перейняти Java, якщо ви дуже мало ресурсів або ваша компанія насправді мала.

Я все ще мушу знайти єдине нетривіальне додаток Java, яке містить лише 1 версію для кожного рядка коду чи функціональності (він же без будь-яких специфічних для платформи речей), і він на 100% портативний серед усіх основних JRE.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.