2010-07-22 12 views
29

tôi đã được đưa ra cụm từ sau đây trong một cuộc phỏng vấn:Java Phỏng vấn Câu hỏi: hoàn thiện() phương pháp

Các gọi của phương pháp của một đối tượng hoàn thiện() là điều cuối cùng điều đó xảy ra trước khi một đối tượng là garbaged được thu thập.

tôi phải trả lời bằng cách:

  • Đúng
  • False

tôi đã chọn True nhưng nó đã sai. Bạn có thể giải thích tại sao không?

+0

Vui lòng đọc bài viết này: http://www.codeguru.com/java/tij/tij0051.shtml –

+0

@Vash, bài viết đó là rất out-of-date – finnw

Trả lời

58

Trình tự là khác nhau:

  1. Đầu tiên đối tượng là thu.
  2. Sau đó, đối tượng là hoàn tất.

Xem http://java.dzone.com/articles/ocajp-7-object-lifecycle-java

vòng đời đối tượng:

  1. Created
  2. Trong sử dụng (mạnh mẽ có thể truy cập)
  3. vô hình
  4. Unreachable
  5. Collected
  6. Hoàn
  7. deallocated
+2

Đã xác nhận. * thu thập * không phải là trạng thái cuối cùng của vòng đời của đối tượng, nó được * deallocated *. +1 cho liên kết và học một cái gì đó ngày hôm nay :) –

+0

Cảm ơn bạn rất này. Kiến thức rất hữu ích. – Cambium

+1

Liên kết bị hỏng! –

2

Không đảm bảo rằng finalize() sẽ luôn được gọi hoặc thậm chí là bộ sưu tập rác đó sẽ chạy hoàn toàn.

Giả sử chương trình của bạn kết thúc (bằng cách gọi System.exit() hoặc khi tất cả các chủ đề đang chạy kết thúc), thì JVM sẽ thoát, nó sẽ không dọn sạch mọi thứ và gọi finalize() trên tất cả các đối tượng.

Do đó, việc đặt các tác vụ dọn dẹp hoàn toàn phải chạy theo phương pháp finalize() không phải là một ý tưởng hay.

+8

này không trả lời câu hỏi – unbeli

+0

Nó phần nào câu trả lời câu hỏi và đưa ra một số thông tin hữu ích về lý do tại sao 'finalize()' không hữu ích như nhiều lập trình viên nghĩ. – Jesper

+0

nó có thể là tốt đẹp để phun đố hữu ích xung quanh, nhưng nó thậm chí còn đẹp hơn để dính vào chủ đề. – unbeli

8

Tôi nghĩ rằng nó gợi ý rằng thực tế là có thực sự những thứ khác có thể được thực hiện/xảy ra đối tượng trước khi GC thực sự loại bỏ nó.

Để trích dẫn tài liệu tham khảo:

[...] Phương pháp Finalize có thể mất bất kỳ hành động , bao gồm cả việc đối tượng này sẵn một lần nữa để đề khác; Tuy nhiên, mục đích thông thường là hoàn thành, , là thực hiện các hành động dọn dẹp trước khi đối tượng được hủy bỏ không hủy ngang. Ví dụ, phương pháp Finalize cho một đối tượng đại diện cho một kết nối đầu vào/đầu ra có thể thực hiện giao dịch I/O rõ ràng để phá vỡ kết nối trước khi đối tượng là vĩnh viễn bỏ đi. [...]

Vì vậy, trong ánh sáng này, quá trình hoàn thiện không phải là điều cuối cùng trước khi GC loại bỏ nó.

2

Tôi đoán bạn có thể bảo vệ cả hai câu trả lời, finalize() được gọi bởi các nhà sưu tập rác trước khi nó thu thập các đối tượng, nhưng bạn không thể chắc chắn rằng sẽ không bao giờ là trường hợp trước khi apllication kết thúc. Không phải tất cả các vật thể bất hợp pháp là rác thu thập phải được thu thập. Bạn có thể không bao giờ phụ thuộc vào phương thức finalize() để được gọi cho bất kỳ đối tượng nào.

1

Đơn đặt hàng sai, như DR đã được hiển thị.

Một đối tượng thay đổi trạng thái thành được thu thập khi gc đã nhận ra rằng đối tượng không thể truy cập được.

Vì vậy, ai nên thực hiện hành động để hoàn thành một đối tượng trước khi điều kiện 'không thể truy cập' này được phát hiện? Trong thực tế, đó là bộ thu gom rác đánh dấu các đối tượng được thu thập để hoàn thành (nếu các đối tượng hoàn thành phương thức được ghi đè). Và chúng tôi thực sự không muốn hoàn thành các đối tượng vẫn có thể truy cập, ví dụ: 'đang sử dụng'.

Câu hỏi hay, vì bạn có xu hướng nói 'có đúng'.

0

Bạn có thể hồi sinh đối tượng trong phương thức hoàn thiện bằng cách tạo một điểm gì đó cho nó để đối tượng có thể không được GC thu thập sau khi gọi phương thức hoàn tất. nhưng khi đối tượng một lần nữa trở nên có sẵn để thu gom rác, nó sẽ không gọi phương thức đã hoàn thành của đối tượng đó vì nó đã được đánh dấu/gắn cờ là đã hoàn thành. vì vậy trước khi GC nó có thể xảy ra gọi phương thức finalize hoặc đối tượng có thể hồi sinh.