2009-01-11 43 views
6

Như câu hỏi, một số vấn đề chung/chính mà các lập trình viên C++ gặp phải khi chuyển sang Java là gì? Tôi đang tìm kiếm một số tên hoặc ví dụ về chủ đề rộng và các điều chỉnh hàng ngày mà các kỹ sư phải thực hiện. Sau đó tôi có thể đi và làm một bài đọc chuyên sâu về điều này.Một số cạm bẫy Java phổ biến/gotchas cho lập trình C++ là gì?

Tôi đặc biệt quan tâm đến ý kiến ​​của các kỹ sư đã từng làm việc trong C++ trong nhiều năm và phải làm việc với Java nhưng bất kỳ gợi ý nào từ người khác hoặc thậm chí đề xuất sách đều được hoan nghênh.

Trả lời

15
  • Trong C++, bạn sẽ sử dụng trình phá hủy để xóa bộ mô tả tệp, kết nối cơ sở dữ liệu và các loại tương tự. Tương đương ngây thơ là sử dụng finalizers. Đừng. Không bao giờ.

Thay vì sử dụng mô hình này:

OutputStream os; 
try { 
    os = ... 
    // do stuff 
} finally { 
    try { os.close(); } catch (Exception e) { } 
} 

Bạn sẽ kết thúc làm những thứ như thế rất nhiều.

  • Nếu bạn chỉ định không modifer truy cập, trong Java các thành viên là gói tin theo mặc định, không giống như C++, trong đó họ là tư nhân. Gói riêng tư là một mức truy cập gây phiền nhiễu có nghĩa là nó là riêng tư nhưng bất kỳ thứ gì trong cùng một gói có thể truy cập nó (đó là một mức độ truy cập mặc định ngu ngốc imho);
  • Không có ngăn xếp ngăn xếp/ngăn xếp. Tất cả mọi thứ được tạo ra trên heap (tốt, đó không phải là đúng sự thật nhưng chúng tôi sẽ giả vờ nó là);
  • Không có tham chiếu vượt qua;
  • Tương đương với con trỏ hàm là giao diện ẩn danh.
+1

đèo bằng cách tham chiếu/giá trị rất đáng đọc về: http://www.yoda.arachsys.com/java/passing.html – Dolph

3

Làm quen với việc thu gom rác. Không thể dựa vào một destructor để dọn sạch tài nguyên mà GC không xử lý.

Mọi thứ đều được chuyển bởi giá trị, bởi vì tham chiếu được chuyển thay vì đối tượng.

Không có hàm tạo bản sao nào, trừ khi bạn cần sao chép. Không có toán tử gán.

Tất cả các phương thức đều là ảo theo mặc định, điều này ngược lại với C++.

Hỗ trợ ngôn ngữ rõ ràng cho giao diện - lớp ảo thuần túy trong C++.

7

Vượt rào cản lớn nhất của tôi từ C++ tới Java là bỏ qua mã thủ tục. Tôi đã rất quen với việc buộc tất cả các đồ vật của mình lại với nhau trong các thủ tục. Nếu không có mã thủ tục trong java, tôi đã tham khảo vòng tròn ở khắp mọi nơi. Tôi phải học cách gọi đồ vật từ vật thể mà không có họ là người phụ thuộc lẫn nhau. Đó là rào cản lớn nhất nhưng dễ nhất để vượt qua.

Số 2 vấn đề cá nhân là tài liệu. JavaDoc rất hữu ích nhưng đối với nhiều dự án java thì theo quan niệm sai lầm rằng tất cả những gì cần là JavaDoc. Tôi thấy tài liệu tốt hơn trong các dự án C++. Đây có thể chỉ là sở thích cá nhân đối với tài liệu bên ngoài mã.

Số 3.Trên thực tế, có con trỏ trong java, chỉ cần không có số học con trỏ. Trong java, chúng được gọi là tài liệu tham khảo . Đừng nghĩ rằng bạn có thể bỏ qua nơi mọi thứ đang chỉ vào, nó sẽ trở lại với một vết cắn lớn.

  • == và .equals không bằng nhau.

  • == sẽ xem con trỏ (tham chiếu) trong khi .equals sẽ xem xét giá trị mà tham chiếu trỏ đến.

+0

thể bạn vui lòng giải thích loại tham chiếu vòng tròn mà bạn có thể sử dụng trong C++ nhưng không phải trong Java? –

+0

Tôi sẽ chỉnh sửa để làm rõ. Những gì tôi đã cố gắng để nói là khi tôi lần đầu tiên bắt đầu viết mã trong java tôi bắt đầu làm tham khảo vòng tròn vì tôi không thể mã procedurally. Nó được coi là, ít nhất là bởi các nhà phát triển mà tôi biết, hình thức xấu để làm cho tài liệu tham khảo vòng tròn. – WolfmanDragon

2

Đó là tất cả những khác biệt nhỏ về cú pháp bit có được. Thiếu các destructors.

Mặt khác, có thể viết chính cho mỗi lớp (vô cùng tiện dụng hoặc thử nghiệm) là thực sự tốt đẹp; sau khi bạn quen với nó, cấu trúc và thủ thuật có sẵn với các tệp jar thực sự tốt đẹp; thực tế là ngữ nghĩa được xác định hoàn toàn (ví dụ, int là giống nhau ở khắp mọi nơi) là thực sự tốt đẹp.

5

Vì bạn đề cập đến các đề xuất sách, hãy đọc số Effective Java, 2nd ed. —địa chỉ hầu hết các cạm bẫy mà tôi đã thấy được liệt kê trong câu trả lời.

+0

Thứ hai này. Đây là một cuốn sách nhỏ tuyệt vời được viết để trả lời các câu hỏi mà bạn có (cạm bẫy, gotchas và thực hành tốt nhất). –

1

Sách hay nhất về "gotchas" Java mà tôi đã đọc là Java Puzzlers: Traps, Pitfalls, and Corner Cases. Đó là không phải là dành riêng cho các nhà phát triển C++, nhưng nó có đầy đủ các ví dụ về những thứ bạn muốn tìm kiếm.

0

Tất cả các phương pháp đều là ảo.

loại tham số (generics) không thực sự tạo Mã thông số cụ thể mã (tức là, List<String> sử dụng bytecode giống như List<Object>; trình biên dịch là điều duy nhất mà phàn nàn nếu bạn cố gắng đặt dấu Integer trong cũ).

Biến thể dễ dàng.

4
  • Không đa kế thừa, và mỗi lớp ngầm xuất phát từ java.lang.Object (trong đó có một số phương pháp quan trọng bạn chắc chắn phải biết và hiểu)
  • Bạn có thể có một loại đa kế thừa bằng cách thực hiện giao diện
  • Không có quá tải toán tử ngoại trừ '+' (cho Strings), và chắc chắn không ai có thể tự làm
  • Không có loại số chưa ký, ngoại trừ char, không thực sự được sử dụng làm loại số. Nếu bạn phải đối phó với các loại unsigned, bạn phải làm rất nhiều đúc và mặt nạ.
  • Chuỗi không được kết thúc bằng null, thay vào đó chúng được dựa trên mảng char và vì vậy không thay đổi. Kết quả là, xây dựng một String dài bằng cách nối với + = trong một vòng lặp là O (n^2), vì vậy đừng làm điều đó; sử dụng một StringBuilder để thay thế.
+0

Plus: không có tùy chọn 'pass by value' cho các đối tượng. –

2

Vấn đề tồi tệ nhất của tôi là luôn ghi nhớ quyền sở hữu trí nhớ. Trong C++, đó là một điều cần thiết để làm, và nó tạo ra một số mẫu trong tâm trí của nhà phát triển khó có thể vượt qua. Trong Java, tôi có thể quên nó (đến một mức độ rất cao, dù sao), và điều này cho phép một số thuật toán và phương pháp tiếp cận mà sẽ là cực kỳ khó xử trong C + +.

5

Tạo một tài liệu tham khảo một cách tình cờ khi một người đã nghĩ đến việc một constructor sao chép:

myClass me = new myClass(); 
myClass somebodyElse = me; /* A reference, not a value copied into an independent instance! */ 
somebodyElse.setPhoneNumber(5551234); 
/* Hey... how come my phone doesn't work anymore?!?!? */ 
+0

Tôi tưởng tượng rằng một lập trình viên C là một trong những người được trang bị nhiều nhất để hiểu điều này, cho mối quan hệ mật thiết với con trỏ và các giá trị tham chiếu. –

2

Không có đối tượng trong Java, chỉ có tham chiếu đến các đối tượng. Ví dụ:

MyClass myClass; // no object is created unlike C++. 

Nhưng:

MyClass myClass = new MyClass(); // Now it is a valid java object reference. 
0

Xác định một số phương pháp như thức không có nghĩa là những gì bạn lúc đầu nghĩ rằng nó có nghĩa là

private void doSomething(final MyObject myObj){ 
    ... 
    myObj.setSomething("this will change the obj in the calling method too"); 
    ... 
} 

vì java là đi qua giá trị nó được làm những gì bạn đang yêu cầu, chỉ cần không rõ ràng ngay lập tức trừ khi bạn hiểu cách java chuyển giá trị của tham chiếu thay vì đối tượng.

0

Một điều đáng chú ý khác là từ khóa finalconst. Java định nghĩa const là một từ khóa dành riêng nhưng không xác định phần lớn việc sử dụng nó. Cũng

object1=object2 

không sao chép các đối tượng nó thay đổi tham chiếu

Các vấn đề liên quan