2015-02-09 21 views
5

Đây chỉ là một quan điểm học tập học thuật. Tất cả những gì tôi biết là bất cứ khi nào chúng ta muốn làm cho một số lớp bất biến, - nó phải bao gồm các trường nguyên thủy cuối cùng - tham chiếu không thoát trong khi xây dựng đối tượng - nếu sử dụng các đối tượng khác, thì các đối tượng đó cũng cần phải đệ quy không thay đổi hoặc các lớp không thay đổi API như java.lang.String, trong số một số thông tin chi tiết khác!Làm thế nào để tạo một lớp không thay đổi với đối tượng Date trong đó?

Nhưng gần đây tôi đã xem xét một câu hỏi trong đó một người phỏng vấn đã yêu cầu một ứng viên tạo ra một lớp không thay đổi có java.util.Date trong đó. Ấn tượng đầu tiên của tôi nói rằng nó không thể mặc dù chúng ta có thể thực hiện các cách giải quyết với String chứa chuỗi ngày tháng thay vì trong đối tượng Date.

Hãy làm rõ tôi về điều này. Cảm ơn bạn.

+1

Fields không cần phải là loại không thay đổi, họ chỉ có thể không được đột biến. –

+0

đơn giản làm cho nó (lớp) cuối cùng !!! –

+1

Và câu hỏi của bạn là gì? Bạn thấy vấn đề với một trường có kiểu 'Date' ở đâu? Đó là lập trình viên nếu anh ta chuyển thể hiện Date này đến lớp gọi. Anh ta không bị buộc phải làm như vậy và do đó nó không phải là một vấn đề để có loại lĩnh vực như vậy. – Tom

Trả lời

15

Điều đơn giản nhất để làm ở đây để làm cho lớp học bất biến là tạo ra một bản sao phòng thủ của đối tượng Date (khi nó được thông qua trong các thông số xây dựng). Sau đó, không cung cấp bất kỳ setters là tốt. Giống như điều này không có tham chiếu đến trường Date trong lớp được hiển thị cho mã bên ngoài lớp này và do đó không thể sửa đổi ngày.

Xem nhận xét của Tom về đặc điểm getter bắt buộc! Cảm ơn bạn đã thêm.

(. Getter nên trả về một bản sao của trường ngày là tốt, kể từ ngày chính nó là có thể thay đổi, và thay đổi lĩnh vực trở về từ các getter sẽ thay đổi trường của lớp cũng)

Để biết thêm thông tin chi tiết: http://www.informit.com/articles/article.aspx?p=31551&seqNum=2

+5

Và nếu có cần phải có một phương thức getter như 'public Date getDate() {}', sau đó tạo một bản sao trong đó: 'return new Date (privateDate.getTime());'. – Tom

+0

Câu trả lời là hoàn hảo với liên kết đã cho trong đó ... Bản sao phòng thủ được giải thích rõ ràng. – minhas23

+1

Trong khi thực hiện các công cụ, tùy chọn tốt hơn tôi cảm thấy là sử dụng String cho ngày được định dạng hoặc biến dài cho epochToDate. – xploreraj

5

Tôi đề xuất tạo lớp bao quanh ngày bạn đang sử dụng và không cung cấp bất kỳ trình cài đặt nào hoặc bất kỳ phương pháp nào thực sự có thể thay đổi giá trị.

Đối với làm cho nó bất biến bạn cần cân nhắc những điều sau đây:

  1. Bạn cần phải chắc chắn rằng lớp không thể được ghi đè, - làm cho nó là cuối cùng.
  2. Làm cho tất cả các trường là riêng tư và cuối cùng.
  3. Không cung cấp bất kỳ trình cài đặt nào hoặc bất kỳ phương pháp nào thay đổi biến mẫu.
  4. Sao chép một cách thủ công các đối tượng giữa callee và người gọi.

    Cân nhắc this tutorial để biết thêm

+1

Hoặc là, hoặc trả lại một bản sao của Ngày –

+1

Tại sao phải bận tâm với trình bao bọc? Chỉ cần tạo một bản sao (riêng tư), và sau đó * không * sửa đổi nó. –

+1

* bản sao phòng thủ của * các trường có thể thay đổi không nguyên thủy *. – TheLostMind

0

1) Không cung cấp phương thức "setter".

2) Làm cho tất cả các lĩnh vực chính thức và tư nhân

3) Không cho phép các lớp con để ghi đè lên các phương pháp - Khai báo lớp như thức

4) Đối với các biến Ví dụ có thể thay đổi - ngày Ví dụ: Trong trường hợp này đặc biệt chú ý đến.

5) Đặt hàm tạo riêng tư và tạo các cá thể trong phương thức của nhà máy. Phương pháp nhà máy để lưu trữ logic tạo đối tượng ở một nơi.

public static MyImmutableClass createNewInstance(Integer fld1, String fld2, Date date) 
{ 
    return new MyImmutableClass (fld1, fld2, date); 
} 

6) Thay vào đó, đối tượng Ngày mới, với nội dung được sao chép vào nó, phải được trả lại.

public Date getDateField() { 
    return new Date(dateField.getTime()); 
} 

- Đây DateField là lĩnh vực mà được thiết lập bên trong xây dựng tư nhân

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