2009-02-26 9 views
10

Java có thực sự hỗ trợ truyền qua tham chiếu không?Java có vượt qua tham chiếu không?

Nếu không, tại sao chúng ta có toán tử == để tìm hai đối tượng có cùng tham chiếu?

+0

Gọi bằng cách tham chiếu và chuyển qua tham chiếu là cùng một điều, phải không? Nếu không, ai đó có thể thay đổi câu hỏi về nó là gì. –

+0

Java hỗ trợ chuyển các bản sao tham chiếu (không phải tài liệu tham khảo gốc), để bất kỳ thay đổi nào về các tham chiếu bên trong phương thức không được phản ánh bên ngoài nó. Kiểm tra điều này: [Java - pass bằng tham chiếu hoặc truyền theo giá trị] (http://programmergate.com/java-pass-reference-pass-value/) –

Trả lời

14

Sử dụng Java truyền theo giá trị, không phải bằng tham chiếu ...

Nhưng đối với các loại nguyên thủy thì giá trị là giá trị của tham chiếu.

Vì vậy, == so sánh giá trị của tham chiếu cho Đối tượng.

+0

Nhưng ở cấp độ byte-mã, nó có tham chiếu ... phải không? https://en.wikipedia.org/wiki/Java_bytecode –

3

Java không sử dụng tính năng tham chiếu mà không phải là giá trị theo từng giá trị. Các thông số giá trị nguyên thủy được sao chép vào ngăn xếp, cũng như các con trỏ tới các đối tượng.

Toán tử == nên được sử dụng để so sánh các giá trị nguyên thủy và để so sánh các tham chiếu đối tượng.

2

Câu trả lời ngắn gọn là không. Trong Java, chỉ có giá trị theo từng lần và khi bạn đang làm việc với các đối tượng (ví dụ: Object obj = new Object();), bạn đang làm việc với các tham chiếu đối tượng. Mà được thông qua bởi giá trị.

Để biết chi tiết, xem: Parameter passing in Java

4

Mấu chốt của sự khác biệt là giữa "vượt qua ** - by- tài liệu tham khảo" và "vượt qua ing một tài liệu tham khảo **". Đôi khi bạn cũng thấy "call-by -..." và "pass-by -..." được sử dụng thay thế cho nhau. Để đơn giản, tôi sẽ gắn bó với "pass-by -...".

  1. Trong học tập, trường học cũ, FORTRAN có liên quan, thuật ngữ comp-khoa học viễn tưởng, pass-by-reference có nghĩa là được gọi là mã có quyền truy cập (tham khảo) cho một biến đi ngang qua người gọi. Chỉ định tham số chính thức trong mã được gọi thực sự thực hiện gán cho biến của người gọi. Sự khác biệt là so với (trong số những người khác) pass-by-value, cung cấp cho mã được gọi là một bản sao của dữ liệu (bất kể nó là gì) được gọi cho người gọi.

  2. Trong thế giới tương đương Java hiện tại, thế giới OO, "có tham chiếu" đối tượng có nghĩa là có thể truy cập vào đối tượng đó. Điều này được phân biệt với "có một con trỏ" để nhấn mạnh (trong số những thứ khác) mà người ta không làm "số học con trỏ" trên một tham chiếu. (Trong thực tế, một "tham chiếu" theo nghĩa này không nhất thiết phải là một địa chỉ bộ nhớ giống con trỏ thực tế.)

Java đối số theo giá trị (theo nghĩa thứ nhất), nhưng đối số đối tượng, giá trị là một tham chiếu (theo nghĩa thứ hai). Dưới đây là một chút mã dựa trên sự khác biệt.

// called 
public void munge(List<String> a0, List<String> a1) { 
    List<String> foo = new List<String>(); foo.add("everybody"); 
    a0.set(0, "Goodbye"); 
    a1 = foo; 
} 

// caller 
... 
List<String> l0 = new List<String>(); l0.add("Hello"); 
List<String> l1 = new List<String>(); l1.add("world"); 
munge(l0, l1); 
... 

Khi trở về từ munge, danh sách đầu tiên của người gọi, l0 sẽ chứa "Goodbye". Tham chiếu đến danh sách đó được chuyển đến munge, được gọi là phương thức đột biến trên đối tượng được đề cập đó.(Nói cách khác, a0 nhận một sao chép về giá trị của l0, mà là một tham chiếu đến một danh sách chuỗi đó đã sửa đổi.)

Tuy nhiên, khi trở về từ munge, danh sách thứ hai của người gọi, l1 vẫn chứa "world" vì không có phương pháp nào được gọi trên tham chiếu đối tượng được truyền (giá trị của l1, được chuyển bởi giá trị đến munge). Thay vào đó, biến đối số a1 được đặt thành giá trị mới (tham chiếu đối tượng địa phương cũng được giữ trong foo).

NẾU Java đã dùng pass-by-reference, sau đó khi trở về, l1 lẽ đã từng chứa "everybody"a1 sẽ giới thiệu đến biếnl1 và không chỉ đơn giản được khởi tạo một bản sao của giá trị của nó. Do đó, việc gán cho a1 cũng sẽ được gán cho l1.

Vấn đề tương tự này đã được thảo luận trong another question, với nghệ thuật ASCII để minh họa cho tình huống.