2017-06-25 36 views
5

Tôi có một vấn đề lớn để hiểu tại sao lớp trình bao bọc trong Java không hoạt động như một kiểu tham chiếu. Ví dụ:Tại sao lớp trình bao bọc trong Java không hoạt động như một kiểu tham chiếu?

Integer one = 10; 
Integer two = one; 
one = 20; 
System.out.println(one); 
System.out.println(two); 

Kết quả sẽ là:

Tôi nghĩ rằng two sẽ là 20 như trong ví dụ này, nơi tôi có thể tạo lớp của riêng tôi:

class OwnInteger { 
     private int integer; 

     public OwnInteger(int integer) { 
      this.integer = integer; 
     } 

     public int getInteger() { 
      return integer; 
     } 

     public void setInteger(int integer) { 
      this.integer = integer; 
     } 
    } 

    OwnInteger one = new OwnInteger(10); 
    OwnInteger two = one; 
    one.setInteger(20); 
    System.out.println(one.getInteger()); 
    System.out.println(two.getInteger()); 

Vì vậy, câu hỏi, là bao gói Integer pper class đặc biệt? Tại sao nó hoạt động như tôi đã chỉ ra trong các ví dụ của tôi?

+4

Có sự khác biệt lớn giữa 'one = 20;' và 'one.setInteger (20);', và nó không liên quan gì đến các lớp bao bọc. 'one = 20;' của đoạn đầu tiên sẽ tương đương với 'one = new OwnInteger (20);' trong đoạn thứ hai. – Eran

+1

Các lớp này hoạt động chính xác như các loại tham chiếu, có thể là do chúng _are_ loại tham chiếu. Khi bạn trỏ một tham chiếu đến một đối tượng khác, bạn không thay đổi con trỏ khác. Các con trỏ độc lập. Nó chỉ thay đổi thành _object_ được hiển thị qua bất kỳ con trỏ nào đến cùng một _object_. Hãy nhớ rằng như JLS nói, Java "tài liệu tham khảo ... là con trỏ". –

Trả lời

8

Đây chính là hành vi của một tài liệu tham khảo kiểu. Trong ví dụ của bạn, two tham chiếu cùng một đối tượng là one sau khi gán. Tuy nhiên, việc gán lại one một đối tượng mới không ảnh hưởng đến two, đó là hành vi mà bạn thấy.

Bạn sẽ thấy những hành vi tương tự với các đối tượng tham khảo khác là tốt, ví dụ

StringBuilder one = new StringBuilder("10"); 
StringBuilder two = one; 
one = new StringBuilder("20"); 
// two still references StringBuilder with "10" 

Để cho một lớp học tài liệu tham khảo để triển lãm các hành vi khi thay đổi một đối tượng cũng thay đổi khác, lớp cần phải được có thể thay đổi, như lớp OwnInteger trong mã của bạn, mã cần thay đổi đối tượng thay vì gán lại nó. Các lớp trình bao bọc, chẳng hạn như Integer, là không thay đổi, do đó bạn sẽ không gặp phải hành vi đó với chúng.

3

Tôi nghĩ rằng hai sẽ là 20 ...

nop, khi bạn làm điều này

Integer two = one; 
one = 20; 

bạn đang thực sự gán một đối tượng mới vào biến one và biến two sẽ không được cập nhật với những thay đổi đó ...

cho lớp của bạn OwnInteg er

OwnInteger one = new OwnInteger(10); 
OwnInteger two = one; 
one.setInteger(20); 

họ làm những gì bạn mong đợi vì onetwo được trỏ đến các tài liệu tham khảo cùng ..

đang A sẽ tương đương với

OwnInteger one = new OwnInteger(10); 
OwnInteger two = one; 
one = new OwnInteger(20); //one.setInteger(20); 
+0

"một và hai đang trỏ đến cùng một tham chiếu .." Sai, chúng đang trỏ đến cùng một _object_. –

0
one = 20; 

sử dụng "quyền anh", và thực sự là tương đương với điều này:

one = Integer.valueOf(20); 

Trong phương pháp trường hợp valueOf bạn tạo một đối tượng mới và trả về một tham chiếu đối tượng mới được tạo ra bởi vì trước đó không tồn tại trong bộ nhớ cache .

Đối với lớp học của riêng bạn onetwo cả hai biến tham chiếu đều trỏ đến cùng một đối tượng.

+0

Điều tương tự cũng đã xảy ra ngay cả khi không có autoboxing, đó không phải là lý do cho sự quan sát của OP. –

0

Các câu trả lời khác cho đến nay tất cả đều ít nhất là một phần sai. Hiệu ứng bạn thấy không liên quan gì đến tính năng tự động hoặc khả năng tắt tiếng. Thay đổi một con trỏ như bước đầu tiên của bạn và thay đổi một đối tượng thông qua một con trỏ như bước thứ hai của bạn là những thứ hoàn toàn khác nhau. Thay đổi con trỏ chỉ nó vào một đối tượng khác. Bạn đã không thay đổi cả hai con trỏ để họ chỉ vào các đối tượng khác nhau. Điều này xảy ra bất kể sự biến đổi hoặc chuyển đổi quyền anh.

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