Sự khác biệt chính giữa C # và Java là gì?


209

Tôi chỉ muốn làm rõ một điều. Đây không phải là một câu hỏi về cái nào tốt hơn, phần mà tôi để cho người khác thảo luận. Tôi không quan tâm đến nó. Tôi đã được hỏi câu hỏi này trong cuộc phỏng vấn xin việc của tôi và tôi nghĩ rằng nó có thể hữu ích để tìm hiểu thêm một chút.

Đây là những cái tôi có thể nghĩ ra:

  • Java là "nền tảng độc lập". Ngày nay bạn có thể nói có dự án Mono nên C # cũng có thể được xem xét nhưng tôi tin rằng nó hơi cường điệu. Tại sao? Chà, khi một bản phát hành Java mới được thực hiện, nó đồng thời có sẵn trên tất cả các nền tảng mà nó hỗ trợ, mặt khác có bao nhiêu tính năng của C # 3.0 vẫn còn thiếu trong triển khai Mono? Hay đó thực sự là CLR so với JRE mà chúng ta nên so sánh ở đây?
  • Java không hỗ trợ các sự kiện và đại biểu. Theo như tôi biết.
  • Trong Java tất cả các phương thức là ảo
  • Các công cụ phát triển: Tôi tin rằng chưa có một công cụ nào như Visual Studio. Đặc biệt là nếu bạn đã làm việc với các phiên bản nhóm, bạn sẽ hiểu ý của tôi.

Vui lòng thêm những người khác mà bạn nghĩ là có liên quan.

Cập nhật: Chỉ cần bật lên tâm trí của tôi, Java không có cái gì đó giống như các thuộc tính tùy chỉnh trên các lớp, phương thức, v.v.


1
Ngôn ngữ khác với triển khai ngôn ngữ, cũng khác với thư viện. Bạn đang cố gắng so sánh điều gì?
Miguel Ping


2
Tôi tìm thấy cái này msdn.microsoft.com/en-us/l Library / ms836794.aspx Nó bao gồm cả sự tương đồng và khác biệt giữa C # và java.
Bipul

1
Bạn có thể nhận được nhiều điều được đề cập dưới đây về Java với các thư viện phù hợp. Kiểm tra ví dụ mã Java hợp lệ này: new String [] {"james", "john", "john", "eddie"} .where (startedWith ("j")). Differ (); Nó sử dụng một thư viện gọi là lombok-pg. Có thể được tìm thấy tại github.com/nicholas22/jpropel
NT_

Câu trả lời:


329

So sánh Java 7 và C # 3

(Một số tính năng của Java 7 không được đề cập ở đây, nhưng usinglợi thế tuyên bố của tất cả các phiên bản C # so với Java 1-6 đã bị xóa.)

Không phải tất cả các tóm tắt của bạn là chính xác:

  • Trong các phương thức Java là ảo theo mặc định nhưng bạn có thể làm cho chúng cuối cùng. (Trong C #, chúng được niêm phong theo mặc định, nhưng bạn có thể biến chúng thành ảo.)
  • Có rất nhiều IDE cho Java, cả miễn phí (ví dụ: Eclipse, Netbeans) và thương mại (ví dụ IntelliJ IDEA)

Ngoài ra (và những gì trong bản tóm tắt của bạn đã có):

  • Generics là hoàn toàn khác nhau giữa hai; Java generic chỉ là một "mánh khóe" thời gian biên dịch (nhưng là một công cụ hữu ích ở đó). Trong C # và .NET generic cũng được duy trì tại thời gian thực hiện và hoạt động cho các loại giá trị cũng như các loại tham chiếu, giữ hiệu quả thích hợp (ví dụ List<byte>như là một byte[]bản sao lưu, thay vì một mảng các byte được đóng hộp.)
  • C # không có ngoại lệ được kiểm tra
  • Java không cho phép tạo các loại giá trị do người dùng định nghĩa
  • Java không có quá tải toán tử và chuyển đổi
  • Java không có các khối trình lặp cho việc lặp lại đơn giản các trình vòng lặp
  • Java không có gì giống như LINQ
  • Một phần do không có đại biểu, Java không có gì giống như các phương thức ẩn danh và các biểu thức lambda. Các lớp bên trong ẩn danh thường điền vào các vai trò này, nhưng vụng về.
  • Java không có cây biểu thức
  • C # không có lớp bên trong ẩn danh
  • Thực tế, C # hoàn toàn không có các lớp bên trong của Java - tất cả các lớp được lồng trong C # giống như các lớp lồng nhau tĩnh của Java
  • Java không có các lớp tĩnh (không có bất kỳ hàm tạo cá thể nào và không thể được sử dụng cho các biến, tham số, v.v.)
  • Java không có bất kỳ loại nào tương đương với các loại ẩn danh C # 3.0
  • Java không hoàn toàn gõ các biến cục bộ
  • Java không có các phương thức mở rộng
  • Java không có các biểu thức khởi tạo bộ sưu tập và đối tượng
  • Các công cụ sửa đổi truy cập có phần khác nhau - trong Java (hiện tại) không có tương đương trực tiếp với một hội đồng, do đó không có ý tưởng về khả năng hiển thị "nội bộ"; trong C # không có tương đương với khả năng hiển thị "mặc định" trong Java, có tính đến không gian tên (và kế thừa)
  • Thứ tự khởi tạo trong Java và C # khác nhau một cách tinh tế (C # thực thi các trình khởi tạo biến trước khi gọi chuỗi đến hàm tạo của kiểu cơ sở)
  • Java không có các thuộc tính như một phần của ngôn ngữ; chúng là một quy ước của phương thức get / set / là
  • Java không có mã tương đương với mã "không an toàn"
  • Interop dễ dàng hơn trong C # (và .NET nói chung) so với JNI của Java
  • Java và C # có một số ý tưởng khác nhau về enum. Java là hướng đối tượng hơn nhiều.
  • Java không có chỉ thị tiền xử lý (#define, #if, v.v. trong C #).
  • Java không có tương đương với C # refoutđể truyền tham số bằng tham chiếu
  • Java không có loại tương đương
  • Giao diện C # không thể khai báo các trường
  • Java không có kiểu số nguyên không dấu
  • Java không hỗ trợ ngôn ngữ cho loại thập phân. (java.math.BigDecimal cung cấp một cái gì đó như System.Decimal - với sự khác biệt - nhưng không có hỗ trợ ngôn ngữ)
  • Java không có loại giá trị tương đương
  • Quyền anh trong Java sử dụng các kiểu tham chiếu được xác định trước (nhưng "bình thường") với các thao tác cụ thể trên chúng. Quyền anh trong C # và .NET là một vấn đề minh bạch hơn, với một loại tham chiếu được CLR tạo ra cho quyền anh cho bất kỳ loại giá trị nào.

Điều này không đầy đủ, nhưng nó bao gồm tất cả mọi thứ tôi có thể nghĩ ra.


24
@Brian: Tôi nghĩ rằng các khái quát về Java và các chi tiết của các lớp bên trong khá nhanh chóng dập tắt ý tưởng về việc Java đạt được sự vượt trội thông qua sự đơn giản;)
Jon Skeet

8
@OrangeDog: Mọi người tranh luận rằng hầu hết là tự đùa, IMO. Thật khó để thấy cách bị buộc phải viết một khối thử / cuối cùng rõ ràng ít bị lỗi hơn so với một câu lệnh sử dụng, IMO. Hầu hết các tính năng "bổ sung" của C # so với Java có nghĩa là bạn có thể thoát khỏi việc viết ít mã hơn và mã đó có thể dễ đọc hơn.
Jon Skeet

17
@OrangeDog: Làm thế nào bạn vô tư, không quan tâm? Vâng, tôi là một người đam mê C #, nhưng với kinh nghiệm Java khá quan trọng - sau tất cả, đó là công việc hàng ngày của tôi. Nó không giống như tôi không biết cách sử dụng Java một cách hiệu quả.
Jon Skeet

8
@OrangeDog: Để bắt đầu, hầu hết các nhà phát triển không viết mã bằng cách sử dụng "không an toàn" theo như tôi biết, vì vậy đó là cá trích đỏ. Tôi cũng nghĩ rằng khả năng chứng minh là cá trích đỏ - tôi không nghĩ tính chứng minh chính thức có liên quan nhiều đến việc con người dễ dàng suy luận về mã như thế nào . Quan điểm của tôi là với tư cách là một người khá có kinh nghiệm về cả Java và C #, tôi thấy C # là một ngôn ngữ vượt trội hơn nhiều về năng suất và khả năng đọc. Nếu bạn cảm thấy điều ngược lại, bạn có thể làm rõ mức độ kinh nghiệm của bạn trong cả hai ngôn ngữ? Tôi nghĩ nó khá liên quan đến cuộc thảo luận.
Jon Skeet

21
@OrangeDog: Hơn nữa, tuyên bố của bạn rằng "Có thể làm nhiều việc hơn làm tăng khả năng bạn sẽ làm sai" cũng là một IMO ngụy biện ... bởi vì nó giả định rằng nếu bạn không thể làm gì đó bằng cách sử dụng một tính năng của ngôn ngữ làm cho nó dễ dàng, bạn sẽ không phải làm nó. Điều đó đơn giản là không đúng sự thật - thường thì các nhiệm vụ bạn cần thực hiện trong Java và C # là như nhau, nhưng do thiếu các tính năng, Java khiến việc thực hiện các nhiệm vụ đó trở nên khó khăn hơn. Bằng cách đơn giản hóa tác vụ, tính năng này sẽ giảm khả năng bạn làm sai.
Jon Skeet

24

Sau đây là một tài liệu tham khảo chuyên sâu tuyệt vời của Dare Obasanjo về sự khác biệt giữa C # và Java. Tôi luôn thấy mình đề cập đến bài viết này khi chuyển đổi giữa hai.

http://www.25hoursaday.com/CsharpVsJava.html


2
@Jon Skeet: bạn là nhà phát triển tích cực nhất C #. Tại sao bạn không duy trì phiên bản khác biệt của C # & Java. Tôi cá là mọi người sẽ thích đọc nó.
móng vuốt

1
@claws: Tôi không có thời gian để làm mọi thứ tôi muốn.
Jon Skeet

19
@Winston: Chúng tôi cần một danh sách "sự khác biệt giữa Chuck Norris và Jon Skeet": 1) Chuck Norris luôn có thời gian; Jon phải sửa đổi TimeDatelớp để luôn có thời gian và chưa có thời gian :(
RedFilter

11

C # có các thuộc tính tự động vô cùng tiện lợi và chúng cũng giúp giữ cho mã của bạn sạch hơn, ít nhất là khi bạn không có logic tùy chỉnh trong getters và setters của mình.


10

Các tính năng của C # vắng mặt trong Java • C # bao gồm các loại nguyên thủy hơn và chức năng để bắt các ngoại lệ số học.

• Bao gồm một số lượng lớn các tiện ích công chứng trên Java, nhiều trong số đó, chẳng hạn như quá tải toán tử và các phôi do người dùng định nghĩa, đã quen thuộc với cộng đồng lớn các lập trình viên C ++.

• Xử lý sự kiện là một "công dân hạng nhất", là một phần của ngôn ngữ.

• Cho phép định nghĩa "structs", tương tự như các lớp nhưng có thể được phân bổ trên ngăn xếp (không giống như các thể hiện của các lớp trong C # và Java).

• C # thực hiện các thuộc tính như một phần của cú pháp ngôn ngữ.

• C # cho phép các câu lệnh chuyển đổi hoạt động trên chuỗi.

• C # cho phép các phương thức ẩn danh cung cấp chức năng đóng.

• C # cho phép iterator sử dụng đồng quy thông qua từ khóa năng suất kiểu chức năng.

• C # có hỗ trợ cho các tham số đầu ra, hỗ trợ trả về nhiều giá trị, một tính năng được chia sẻ bởi C ++ và SQL.

• C # có khả năng bí danh không gian tên.

• C # có "Triển khai thành viên rõ ràng" cho phép một lớp thực hiện cụ thể các phương thức của giao diện, tách biệt với các phương thức lớp của chính nó. Điều này cho phép nó cũng thực hiện hai giao diện khác nhau có một phương thức cùng tên. Các phương thức của một giao diện không cần phải công khai; chúng chỉ có thể được truy cập thông qua giao diện đó.

• C # cung cấp tích hợp với COM.

• Theo ví dụ về C và C ++, C # cho phép gọi theo tham chiếu cho các kiểu tham chiếu nguyên thủy và tham chiếu.

Các tính năng của Java vắng mặt trong C #

• Từ khóarictfp của Java đảm bảo rằng kết quả của các hoạt động dấu phẩy động vẫn giống nhau trên các nền tảng.

• Java hỗ trợ các ngoại lệ được kiểm tra để thực thi tốt hơn việc bẫy và xử lý lỗi.


9

Một tài nguyên tốt khác là http://www.javacamp.org/javavscsharp/ Trang web này liệt kê nhiều ví dụ cho thấy hầu hết sự khác biệt giữa hai ngôn ngữ lập trình này.

Về các thuộc tính, Java có Chú thích, hoạt động gần như giống nhau.


5

Generics:

Với các tổng quát Java, bạn thực sự không nhận được bất kỳ hiệu quả thực thi nào mà bạn có được với .NET bởi vì khi bạn biên dịch một lớp chung trong Java, trình biên dịch sẽ loại bỏ tham số kiểu và thay thế Object ở mọi nơi. Chẳng hạn, nếu bạn có một Foo<T>lớp, trình biên dịch java tạo Mã Byte như thể nó là Foo<Object>. Điều này có nghĩa là việc đúc và cả đấm bốc / unboxing sẽ phải được thực hiện trong "nền".

Tôi đã chơi với Java / C # được một thời gian và, theo tôi, sự khác biệt lớn ở cấp độ ngôn ngữ là, như bạn đã chỉ ra, các đại biểu.


Điều này là sai, tổng quát xóa hoặc thống nhất (Java và C # tương ứng) không nhất thiết ảnh hưởng đến hiệu suất.
Miguel Ping

Bạn đang nhầm lẫn autoboxing với đúc.
JesperE

3
Không, bruno đúng về sự khác biệt hiệu suất. Không có cách nào có được tương đương với Danh sách <byte> (nói chung) trong Java. Bạn sẽ phải có một Danh sách <Byte> sẽ phải chịu các hình phạt đấm bốc (thời gian và bộ nhớ).
Jon Skeet

Quyền anh (un) chỉ xảy ra đối với các loại hình hộp, là loại nguyên thủy.
Miguel Ping


0

Vui lòng đi qua liên kết được cung cấp bên dưới msdn.microsoft.com/en-us/l Library / ms836794.aspx Nó bao gồm cả sự tương đồng và khác biệt giữa C # và java

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.