Co różni się między „pisaniem konkretnego środowiska JRE dla każdej platformy” dla programistów Java a „pisaniem kompilatora C ++ dla każdej platformy” dla programistów C ++?
Co różni się między „pisaniem konkretnego środowiska JRE dla każdej platformy” dla programistów Java a „pisaniem kompilatora C ++ dla każdej platformy” dla programistów C ++?
Odpowiedzi:
Java jest kompilowana po uruchomieniu w dowolnym miejscu. C ++ jest napisany po kompilacji w dowolnym miejscu.
„pisanie konkretnego środowiska JRE dla każdej platformy” nie jest czymś, co robisz za każdym razem. Przeniesienie środowiska JRE na nową platformę to czynność, którą należy wykonać tylko raz. To zadanie jest na ogół wykonywane przez głównego opiekuna / programistów programu i / lub platformy. Przy podejmowaniu decyzji, kto i jak zostanie przeniesione środowisko JRE, może mieć wpływ wiele czynników. Między innymi zależy to od licencji, pod którą jest publikowany (słyszę, że Java to Open Source, więc chyba każdy mógłby to zrobić). Śmieszna anegdota, Steve Jobs zrobił wiele o tym , że około roku temu nie chciał zająć się przenoszeniem Java na Maca .
Nie chodzi o to, jak i kto przenosi środowisko JRE, ale o fakt, że po jego przeniesieniu każda aplikacja Java powinna teoretycznie łatwo działać na nowej maszynie. W tym sensie środowisko JRE tworzy warstwę abstrakcji, całkowicie ukrywając maszynę, umożliwiając łatwe przenoszenie.
Jednak rzeczywistość nie zawsze jest taka ładna. Nie posunę się tak daleko, nazywając przenośność „mitem”, ale prawdą jest, że nie jest ona tak idealna. Na przykład Java ma pakiet o nazwie, JNI
który umożliwia wysyłanie wywołań natywnych, z pominięciem środowiska JRE, co uniemożliwia idealną bezproblemową przenośność, którą fani Java lubią nazywać „Napisz wszędzie uruchamiane”.
Jak wspomniano w komentarzach, podejście C ++ do przenośności jest inne. Z jednej strony jest to skompilowany język, a te pliki binarne prawie zawsze są specyficzne dla platformy. Pliki wykonywalne c ++ nigdy nie będą przenośne (w przeciwieństwie do Java). Z drugiej strony, portowanie kompilatora może czasem wystarczyć. Społeczność odkryła, że przez przeniesienie kompilatora, a także niektórych podstawowych bibliotek języka, kody źródłowe (a nie pliki binarne) mogą być przenośne.
Jednak C ++ jest szeroko stosowany w systemach krytycznych, takich jak kompilatory, jądra, systemy czasu rzeczywistego, systemy osadzone ... Istnieje aspekt „niskiego poziomu” C ++, którego nie można przeoczyć, mówiąc o przenośności.
To nie tylko język - to biblioteki.
Zarówno Java, jak i C ++ zapewniają biblioteki wieloplatformowe. Java zapewnia bogatszy zestaw.
Różnica polega na tym, że Java będzie działać na dowolnej platformie bez ponownej kompilacji. Posiadanie kompilatora C ++ dla każdej platformy wcale nie jest takie samo.
Wszystkie odpowiedzi zaczynające się od „Różnica jest…” lub coś bardzo podobnego, są zasadniczo błędne (przepraszam, ale takie jest życie). Istnieją naprawdę dwie odrębne różnice między nimi.
Jedną (o której często wspomniano) jest to, że skompilowany program Java może (lub przynajmniej powinien) działać na dowolnej zgodnej implementacji Java, więc nawet po skompilowaniu nadal możesz przenosić program Java z jednej platformy na drugą bez ponownej kompilacji . C ++ (przynajmniej normalnie) wymaga ponownej kompilacji dla każdej platformy docelowej.
Po drugie, Java (przynajmniej próbuje) zapewnić, że wszystkie poprawnie napisane Java będą przenośne. Przynajmniej teoretycznie nie powinieneś być w stanie napisać żadnego kodu, który nie jest przenośny.
C ++ pozwala ci robić kilka rzeczy, które nie są przenośne. Standard C ++ zawiera „ostrzeżenia” o wielu rzeczach, które nie są przenośne (np. Informujące o tym, że otrzymasz zachowanie zdefiniowane w implementacji lub zachowanie nieokreślone), ale niekoniecznie próbuje Cię powstrzymać . Na przykład, jeśli chcesz napisać system operacyjny dla sprzętu korzystającego z magistrali PCI, prawdopodobnie będziesz musiał odczytać / zapisać pamięć konfiguracji PCI. To oczywiście nie będzie przenośne dla systemów bez magistrali PCI, ale jeśli piszesz system operacyjny dla sprzętu z magistralą PCI, jest to prawie konieczne. C ++ pozwala na to, nawet jeśli oczywiście nie będzie przenośny.
Źle zrozumiałeś przesłankę. Programy Java są bardzo przenośne, ponieważ JVM zapewnia standardowe zachowanie, które jest takie samo. Programy C ++ mają mniej znormalizowane środowisko bliższe rzeczywistemu sprzętowi, więc program musi być w stanie obsłużyć różne szczegóły specyficzne dla platformy - takie jak rozmiar int, wyrównanie słów itp. Itp.
Sam JVM nie jest zbyt przenośny. Herkulesowym zadaniem jest przeniesienie wysokowydajnej maszyny JVM na inną platformę lub architekturę procesora.
Różnica polega na tym, że programy Java (to nie skrót) mogą być dystrybuowane w formie, którą można uruchomić na dowolnym komputerze z zainstalowaną maszyną JVM, ale C ++ jest zwykle dystrybuowany jako dowolny kod źródłowy, który jest bardzo nieprzyjazny dla użytkownika, lub jako grupa różnych plików binarnych dla różnych platform.
Jednym z powodów, dla których Java jest uważana za przenośną, jest to, że ma określone zasady dotyczące wyceny wyrażeń arytmetycznych i zabrania implementacjom ich oceniania w jakikolwiek inny sposób, nawet jeśli ocena ich w mandat wymagałaby wolniejszego kodu niż ocena ich w bardziej dokładny sposób moda.
Na przykład dane
long thing1(int x) {
return (x+1)-1L;
}
double thing2(int x, float y) {
return x/y;
}
Wartości thing1(2147483647)
i thing2(1123456700,11234567.0f)
muszą wynosić odpowiednio -2147483649L i 99.9999923706054688, mimo że poprawne arytmetycznie byłyby 2147483647L i 100,0, a nawet jeśli na niektórych platformach kod do wygenerowania niepoprawnych liczbowo wyników byłby wolniejszy niż kod do wygenerowania poprawnych wyniki (na niektórych platformach 64-bitowych wymuszenie zachowania zawijania po (x + 1) wymagałoby dodatkowej instrukcji, a na platformie 8x87 wymuszenie zaokrąglenia wartości 1123456700 do float
dodatkowej instrukcji w porównaniu z zwykłym ładowaniem bezpośrednio do rejestru o rozszerzonej precyzji).
(int)
do (x+1)
podwyrażenia pierwszego przykładu w pierwszym przykładzie, do float
parametru drugiego przykładu x
, ale oczywiście nie zaprojektowałem tego języka .
Ilość pracy dla narzędzi pomocniczych jest rzeczywiście podobna, różnica leży gdzie indziej. Po skompilowaniu programu C ++ dla platformy musisz go skompilować ponownie, jeśli chcesz go używać na innej platformie. Jednak po skompilowaniu programu Java można przenieść go na dowolną platformę ze środowiskiem wykonawczym bez konieczności jego ponownej kompilacji.
Odpowiadając na tytuł „Czy przenośność to mit?”, Zamiast „Który lepszy jest w przenośności, Javie lub C ++”, powiem, że częściowa przenośność jest możliwa, ale pełna przenośność to mit.
Coś, co nalegam na napisanie i dotyczy to tego pytania, polega na tym, że programiści nie pracują już tylko z językami programowania, ale z pełnymi ramami programistycznymi.
A te frameworki obejmują biblioteki, bazy danych, interfejsy graficzne.
Który język programowania lub która struktura programowania jest bardziej przenośna?
To zależy od tego, co twoja aplikacja. próbuje osiągnąć.
Chodzi o to, że „ty” nie piszesz środowiska JRE, piszesz kod Java, który działa na dowolnym środowisku JRE. „Ty” piszesz kod C ++, który może wymagać zmian , zanim skompiluje się na innej platformie.
Wiele osób zapomina lub nie bierze pod uwagę rzeczywistości Java, mówiąc, że „jest w 100% przenośny” lub podobnych zwrotów.
Prawie wszystkie duże korporacje / Software house miały w ostatnim czasie co najmniej 1 domową implementację Java ze skojarzonym JRE, a niektóre nadal ją utrzymują, na przykład Microsoft, IBM i Apple miały swoją własną wersję Java odzwierciedlającą ich własne pomysły i przemyślenia na temat tego, gdzie powinna iść branża i taki język.
Jak to jest w przypadku „przenośnego”? JRE gdziekolwiek się obrócisz.
I to bez uwzględnienia tego, co robi Sun / Oracle.
Przykładem tego, dlaczego kod Java nie jest tak daleki od C i C ++ pod względem przenośności, są GUI i serwery graficzne, Apple miał niestandardową implementację frameworku GUI dla własnego środowiska JRE, w wyniku czego wiele bóle głowy i podwójna praca dla każdego, kto chciał stworzyć / przenieść GUI za pomocą Java na maszyny Apple i byli w zasadzie zmuszeni do radzenia sobie z Quartzem (jak to się ma w przypadku „dźwigni” i języków wysokiego poziomu?).
Czasami nawet najczęściej używane słowa nie odzwierciedlają znaczenia, które ludzie zwykle im nadają, dla mnie termin „przenośność” w świecie Java przypomina bardziej „perspektywę” w zdrowym znaczeniu; pod względem handlowym i finansowym jest lepsza perspektywa , jeśli zastosujesz Javę zamiast innych języków (przynajmniej w momencie narodzin Java), ponieważ masz już dużo pracy po jednej stronie (dostajesz JRE na wszystko które można uznać za „komputer”), a twoja baza kodów prawdopodobnie będzie przenośna, potrzebujesz mniej zasobów do przeniesienia programu, to wszystko, czy wspomniane zasoby to pieniądze, czas lub siła robocza nie ma znaczenia, jest to niższe próg w porównaniu do innych technologii i po to jest Java, obniża ten próg.
Oczywiście jest to prawdą, jeśli zaakceptujesz założenia Javy, co oznacza maszynę wirtualną z funkcją wyrzucania elementów bezużytecznych, co oznacza, że zużywa ona więcej zasobów w porównaniu z językami ojczystymi, jeśli naprawdę chcesz wycisnąć maksimum z procesora lub farmy serwerów I nie myśl, że możesz adoptować Javę, chyba że masz bardzo mało zasobów lub Twoja firma jest naprawdę mała.
Nadal muszę znaleźć jedną nietrywialną aplikację Java, która zawiera tylko 1 wersję dla każdego wiersza kodu lub funkcjonalności (czyli bez żadnych specyficznych dla platformy rzeczy) i jest w 100% przenośna wśród wszystkich głównych środowisk JRE.