Điều gì khác nhau giữa "viết một JRE cụ thể cho từng nền tảng" cho các nhà phát triển Java và "viết một trình biên dịch C ++ cho mỗi nền tảng" cho các nền tảng C ++?
Điều gì khác nhau giữa "viết một JRE cụ thể cho từng nền tảng" cho các nhà phát triển Java và "viết một trình biên dịch C ++ cho mỗi nền tảng" cho các nền tảng C ++?
Câu trả lời:
Java được biên dịch một lần chạy ở bất cứ đâu. C ++ được viết một lần biên dịch ở bất cứ đâu.
"Viết một JRE cụ thể cho từng nền tảng" không phải là việc bạn làm mọi lúc. Chuyển JRE sang một nền tảng mới là điều bạn chỉ cần làm một lần. Nhiệm vụ này thường được thực hiện bởi nhà bảo trì / nhà phát triển cốt lõi của chương trình và / hoặc nền tảng. Rất nhiều yếu tố có thể xuất hiện khi quyết định JRE sẽ được chuyển đến ai và như thế nào. Trong số những thứ khác, nó phụ thuộc vào bản quyền được cấp phép được xuất bản theo (Tôi nghe Java là Nguồn mở, vì vậy tôi đoán bất cứ ai cũng có thể làm được). Giai thoại vui, Steve Jobs đã đưa ra một vấn đề lớn về việc không muốn chăm sóc việc chuyển Java trên Mac , khoảng một năm trước.
Vấn đề không phải là làm thế nào hoặc ai chuyển JRE, mà thực tế là một khi nó được chuyển, mọi ứng dụng Java bây giờ về mặt lý thuyết sẽ dễ dàng chạy trên máy mới. Theo nghĩa đó, JRE tạo thành một lớp trừu tượng, ẩn hoàn toàn máy, cho phép chuyển dễ dàng.
Tuy nhiên, thực tế không phải lúc nào cũng đẹp như thế này. Tôi sẽ không đi xa đến mức gọi tính di động là "huyền thoại", nhưng sự thật là nó không quá hoàn hảo. Chẳng hạn, Java có một gói được gọi là JNI
cho phép gửi các cuộc gọi riêng, bỏ qua JRE, do đó ngăn chặn tính di động liền mạch hoàn hảo, điều mà người hâm mộ Java muốn gọi là "Viết một lần chạy ở mọi nơi".
Như đã đề cập trong các bình luận, cách tiếp cận tính di động của C ++ là khác nhau. Một mặt, đó là một ngôn ngữ được biên dịch và các nhị phân đó hầu như luôn luôn là nền tảng cụ thể. Vì vậy, các tệp thực thi c ++ sẽ không bao giờ có thể mang theo được (không giống như Java). Mặt khác, porting trình biên dịch đôi khi có thể là đủ. Cộng đồng đã phát hiện ra rằng bằng cách chuyển trình biên dịch cũng như một số thư viện cốt lõi của ngôn ngữ, mã nguồn (chứ không phải mã nhị phân) có thể được mang theo.
Tuy nhiên, C ++ được sử dụng rộng rãi trong các hệ thống quan trọng như trình biên dịch, nhân, hệ thống thời gian thực, hệ thống nhúng, ... Có một khía cạnh "mức độ thấp" của C ++ không thể bỏ qua khi nói về tính di động.
Đó không chỉ là ngôn ngữ - đó là các thư viện.
Cả Java và C ++ đều cung cấp các thư viện đa nền tảng. Java cung cấp một tập hợp phong phú hơn.
Sự khác biệt là Java sẽ chạy trên mọi nền tảng mà không cần biên dịch lại. Có một trình biên dịch C ++ cho mỗi nền tảng hoàn toàn không giống nhau.
Tất cả các câu trả lời bắt đầu bằng "Sự khác biệt là ...", hoặc bất cứ điều gì rất giống nhau, về cơ bản là sai (xin lỗi, nhưng đó là cuộc sống). Thực sự có hai sự khác biệt giữa hai.
Một (điều đó đã được đề cập rất nhiều) là một chương trình Java đã biên dịch có thể (hoặc ít nhất nên) chạy trên bất kỳ triển khai tuân thủ nào của Java, vì vậy ngay cả sau khi được biên dịch, bạn vẫn có thể di chuyển chương trình Java từ nền tảng này sang nền tảng khác mà không cần biên dịch lại . C ++ (ít nhất là bình thường) yêu cầu biên dịch lại cho mỗi nền tảng đích.
Mặt khác là Java (ít nhất là cố gắng) đảm bảo rằng tất cả Java được viết chính xác sẽ có thể mang theo được. Ít nhất là về lý thuyết, bạn không nên viết bất kỳ mã nào không di động.
C ++ cho phép bạn thực hiện một số thứ không thể mang theo được. Tiêu chuẩn C ++ chứa "cảnh báo" về rất nhiều thứ không khả dụng (ví dụ: cho bạn biết rằng bạn sẽ thực hiện hành vi được xác định hoặc hành vi không xác định), nhưng không nhất thiết phải cố gắng ngăn bạn thực hiện chúng . Ví dụ, nếu bạn muốn viết một hệ điều hành cho phần cứng sử dụng bus PCI, có lẽ bạn sẽ cần phải đọc / ghi bộ nhớ cấu hình PCI. Điều này rõ ràng sẽ không thể di chuyển đến các hệ thống không có bus PCI, nhưng nếu bạn đang viết một hệ điều hành cho phần cứng bằng bus PCI, điều đó khá cần thiết. C ++ cho phép nó mặc dù rõ ràng nó sẽ không thể mang theo được.
Bạn đã hiểu lầm các cơ sở. Các chương trình Java rất dễ mang theo, vì JVM cung cấp một hành vi tiêu chuẩn được đảm bảo giống nhau. Các chương trình C ++ có môi trường ít tiêu chuẩn hơn gần với phần cứng thực tế, vì vậy chương trình cần có khả năng xử lý các chi tiết cụ thể của nền tảng khác nhau - như kích thước của một int, căn chỉnh từ, v.v.
Bản thân JVM không dễ mang theo. Nhiệm vụ bất thường là chuyển một JVM hiệu năng cao sang một nền tảng hoặc kiến trúc CPU khác.
Sự khác biệt là các chương trình Java (không phải là từ viết tắt) có thể được phân phối ở dạng có thể chạy trên bất kỳ máy tính nào có cài đặt JVM, nhưng C ++ thường được phân phối dưới dạng mã nguồn, rất thân thiện với người dùng hoặc là một bó của các nhị phân khác nhau cho các nền tảng khác nhau.
Một trong những lý do Java được coi là di động là vì nó có các quy tắc cụ thể về cách định giá các biểu thức số học và cấm các triển khai đánh giá chúng theo bất kỳ cách nào khác, ngay cả khi đánh giá chúng theo cách bắt buộc sẽ yêu cầu mã chậm hơn so với đánh giá chúng chính xác hơn thời trang.
Ví dụ, được đưa ra
long thing1(int x) {
return (x+1)-1L;
}
double thing2(int x, float y) {
return x/y;
}
Các giá trị của thing1(2147483647)
và thing2(1123456700,11234567.0f)
được yêu cầu lần lượt là -2147483649L và 99.9999923706054688, mặc dù các giá trị chính xác sẽ là 2147483647L và 100.0, và mặc dù trên một số mã nền tảng để tạo ra kết quả không chính xác về số sẽ chậm hơn mã để tạo ra kết quả không chính xác về số. kết quả (trên một số nền tảng 64 bit, buộc hành vi gói sau (x + 1) sẽ yêu cầu một lệnh bổ sung và trên nền tảng 8x87, buộc giá trị của 1123456700 được làm tròn thành một float
yêu cầu bổ sung so với tải đơn giản nó trực tiếp đến một thanh ghi chính xác mở rộng).
(int)
của ví dụ đầu tiên (x+1)
trong ví dụ đầu tiên, cho tham số float
của ví dụ thứ hai x
, nhưng rõ ràng tôi không thiết kế ngôn ngữ .
Khối lượng công việc cho các công cụ hỗ trợ thực sự tương tự nhau, sự khác biệt nằm ở chỗ khác. Khi một chương trình C ++ đã được biên dịch cho một nền tảng, bạn phải biên dịch lại nếu bạn muốn sử dụng nó trên một nền tảng khác. Tuy nhiên, khi một chương trình java đã được biên dịch, bạn có thể di chuyển nó sang bất kỳ nền tảng nào khác có môi trường thời gian chạy mà không phải biên dịch lại.
Trả lời tiêu đề "Tính di động có phải là một huyền thoại không?", Thay vì "Cái nào tốt hơn về tính di động, Java hay C ++", tôi sẽ nói rằng tính di động một phần là có thể, nhưng tính di động hoàn toàn thì đó là một huyền thoại.
Một cái gì đó mà tôi khăng khăng viết, và nó áp dụng cho câu hỏi này, đó là các nhà phát triển không còn làm việc chỉ với các ngôn ngữ lập trình, mà, với các khung lập trình đầy đủ.
Và những khung đó, bao gồm thư viện, cơ sở dữ liệu, giao diện đồ họa.
Ngôn ngữ lập trình nào, hoặc khung lập trình nào dễ mang theo hơn?
Vâng, nó phụ thuộc vào ứng dụng của bạn. đang cố gắng để đạt được.
Vấn đề là "bạn" không viết JRE mà bạn viết mã Java chạy trên bất kỳ JRE nào . "Bạn" làm viết mã C ++ mà có thể yêu cầu thay đổi bởi bạn trước khi nó sẽ biên dịch trên nền tảng khác.
Nhiều người quên hoặc không tính đến thực tế của Java khi họ nói rằng "đó là 100% di động" hoặc các cụm từ như thế.
Gần như tất cả các Tập đoàn / Nhà phần mềm lớn đều có ít nhất 1 triển khai Java tại nhà với một JRE liên quan trong quá khứ và một số vẫn duy trì nó, ví dụ như Microsoft, IBM và Apple đều có phiên bản Java của riêng họ phản ánh ý tưởng và suy nghĩ riêng về nơi mà ngành công nghiệp và ngôn ngữ như vậy nên đi.
Làm thế nào là "di động"? Một JRE bất cứ nơi nào bạn rẽ.
Và điều này là không cần xem xét những gì Sun / Oracle đã làm.
Một ví dụ về lý do tại sao mã Java không thực sự xa C và C ++ về khả năng di động là GUI và máy chủ đồ họa, Apple đã triển khai khung GUI không chuẩn cho JRE của riêng mình, do đó, có rất nhiều đau đầu và làm việc gấp đôi cho bất cứ ai muốn tạo / chuyển GUI bằng Java cho các máy của Apple và về cơ bản họ buộc phải đối phó với Quartz (làm thế nào về mặt "đòn bẩy" và ngôn ngữ cấp cao?).
Đôi khi, ngay cả những từ được sử dụng phổ biến nhất cũng không thực sự phản ánh ý nghĩa mà mọi người thường dành cho chúng, với tôi thuật ngữ "tính di động" trong thế giới Java giống như "triển vọng" theo nghĩa thông thường; về mặt thương mại và tài chính có triển vọng tốt hơn cho bạn nếu bạn áp dụng Java thay vì các ngôn ngữ khác (ít nhất là tại thời điểm Java ra đời) bởi vì bạn đã thực hiện rất nhiều công việc ở một bên (bạn nhận được JRE về bất cứ điều gì đó có thể được coi là một "máy tính") và cơ sở mã của bạn có khả năng di động vì nó là như vậy, bạn cần ít tài nguyên hơn để chuyển chương trình của mình, đó là, cho dù tài nguyên là tiền, thời gian hay nhân lực không thành vấn đề, nó thấp hơn ngưỡng so với các công nghệ khác và đó là những gì Java dành cho, nó đang hạ thấp ngưỡng đó.
Tất nhiên điều này là đúng nếu bạn chấp nhận các tiền đề của Java, có nghĩa là một máy ảo có bộ sưu tập rác, có nghĩa là nó tiêu tốn nhiều tài nguyên hơn nếu so với ngôn ngữ bản địa, nếu bạn thực sự muốn tận dụng tối đa CPU hoặc máy chủ của bạn đừng nghĩ rằng bạn có thể chấp nhận Java trừ khi bạn thực sự thiếu tài nguyên hoặc công ty của bạn rất nhỏ.
Tôi vẫn phải tìm một ứng dụng Java không tầm thường duy nhất chỉ chứa 1 phiên bản cho mỗi dòng mã hoặc chức năng (còn gọi là không có bất kỳ nội dung cụ thể nào về nền tảng) và nó có thể di động 100% trong số tất cả các JRE chính.