2010-03-12 17 views
10

Trong ứng dụng Java của tôi, tôi có một số bản sao-nhà xây dựng như thế nàyTruy cập vào trường riêng của đối tượng khác trong các nhà xây dựng sao chép - Thực sự là một vấn đề?

public MyClass(MyClass src) { 
    this.field1 = src.field1; 
    this.field2 = src.field2; 
    this.field3 = src.field3; 
... 
} 

Bây giờ Netbeans 6.9 cảnh báo về vấn đề này và tôi tự hỏi những gì là sai với mã này?

mối quan tâm của tôi:

  • Sử dụng thu khí có thể giới thiệu không mong muốn tác dụng phụ. Đối tượng mới có thể không còn được coi là bản sao của bản gốc.
  • Nếu nó được khuyến nghị sử dụng getters, nó sẽ không nhất quán hơn nếu người ta sẽ sử dụng setters cho dụ mới không?

EDIT: Cảnh báo thực tế là "Truy cập của lĩnh vực tư nhân của một đối tượng" và hành động chỉ có sẵn Netbeans cung cấp sẽ bổ sung một @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")

Mã của tôi thực sự là như tầm thường như ví dụ đưa ra.

+0

Cảnh báo từ Netbeans là gì? – Timothy

+0

Cập nhật câu hỏi của tôi –

+1

Tôi chỉ có thể suy đoán về lý do: Một số người nghĩ rằng 'riêng tư' có nghĩa là chỉ có đối tượng * hiện tại có thể truy cập trường (trong khi thực tế các đối tượng khác cùng lớp cũng có thể truy cập trường). Có lẽ cảnh báo này có nghĩa là một lời nhắc nhở rằng điều này là thực sự có thể và để ngăn chặn mọi người làm điều đó một cách vô tình. –

Trả lời

7

Tôi thấy không có vấn đề với mã. Trong thực tế, tôi chia sẻ mối quan tâm của bạn và không muốn sử dụng getters.

Cảnh báo bạn nhận được chính xác là gì? Có lẽ nó liên quan đến một cái gì đó bạn không cho chúng ta thấy?

Cập nhật: Dường như Netbeans thực sự phàn nàn về điều đó. Đó là một cảnh báo khá gây tranh cãi để gửi cùng với một IDE, tôi nghĩ vậy.

+4

Tuyệt đối. Khái niệm riêng tư là dành cho * riêng tư đối với việc triển khai lớp *, theo quan điểm của tôi. Một hàm tạo bản sao là một phần của việc triển khai lớp và có thể làm những gì nó thích với dữ liệu riêng tư. –

+0

Bản sao như vậy là một vấn đề nếu các trường không phải là nguyên thủy, nhưng các trường trong đó nội dung có thể thay đổi. Ngay cả khi bạn muốn, bạn vẫn có thể gặp các vấn đề tương tranh. – extraneon

+0

@extraneon: Điều đó dường như nằm ngoài phạm vi của cảnh báo. Việc đưa mọi thứ vào getters cũng sẽ không tạo nên sự khác biệt ở đó. – Thilo

0

Có lẽ lớp học có thể cung cấp phương thức sao chép nông để biết dữ liệu nào cần trả về trong đối tượng được sao chép. Nếu cần, bạn cũng có thể cung cấp bản in sâu.

public MyClass shallowCopy() { 
    MyClass aCopy = new MyClass(); 
    aCopy.field1 = this.field1; 
    aCopy.field2 = this.field2; 
    aCopy.field3 = this.field3; 
} 
+0

Điều này đưa ra cảnh báo tương tự. –

4

Tôi không biết tại sao NetBeans cảnh báo, nhưng bạn đang tạo một bản sao nông hiệu quả. Bản sao của bạn chia sẻ field1, field2 và field3 với src và như vậy một sửa đổi của field3, nói, một danh sách, sẽ phản ánh trong bản gốc.

private List field1; 

public MyClass(MyClass src) { 
    this.field1 = src.field1; 
    this.field2 = src.field2; 
    this.field3 = src.field3; 

    field1.add(new Object()); // field1 of src also modified 
... 
} 
+0

Điểm tốt, tôi không nghĩ đến các loại có thể thay đổi. Nhưng trong trường hợp này, tôi chỉ sao chép các loại 'int' và' String' –

6

Nó nhắc nhở tôi về các cuộc thảo luận ADT vs Object.

ADT có thể truy cập trạng thái nội bộ của phiên bản ADT khác. Triết lý đối tượng sẽ ngăn chặn điều đó và thực thi truy cập thông qua getter/setter để đảm bảo độc lập đại diện.

Đó là một sự lựa chọn cân nhắc rằng trường hợp biến trong Java là đẳng cấp riêng, không đối tượng tin (Trong trường hợp sau chỉ this.privateInstVar được cho phép, không obj.privateInstVar).

Điều này có cả điểm mạnh lẫn điểm yếu. Tính năng này đặc biệt hữu ích khi nói đến nhân bảnbình đẳng. Mặt khác, nó có thể bị lạm dụng và đóng gói phá vỡ.

Nó gần như là một cuộc tranh luận triết học. Nhưng IMHO, những gì bạn đang làm là tốt.

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