Chào bạn đến với phanlamcoder.blogspot.com!
Ở bài viết này chúng ta sẽ tìm hiểu về Tham trị (pass-by-value) và tham chiếu (pass-by-reference) trong Java
Khi thao tác với các hàm trong Java, với những người mới bắt đầu sẽ thường lúng
túng với việc truyền tham số vào cho các hàm. Tại sao một số trường hợp khi
truyền tham số vào cho hàm xong khi thoát ra khỏi hàm giá trị của tham
số lúc
thì bị thay đổi theo logic của hàm, lúc thì không thay đổi gì? Vấn đề ở đây
chính là sự khác nhau của các loại tham số được truyền vào hàm mà đôi lúc người lập trình
không để ý đến. Các loại tham số này được chia làm 2 kiểu là truyền giá trị và truyền tham chiếu.
·
Truyền tham trị là gì? Truyền tham chiếu là gì?
Mình tạm áp dụng một cách nhớ có vẻ hơi thô thiển của mình để tránh nhầm lẫn trong
trường hợp này: tham
trị là cùng giá trị, tham
chiếu là cùng chiếu đến một vùng nhớ.
1. Truyền tham
trị
là truyền / copy giá trị của một biến (A) vào một biến khác (B) để sử dụng
trong phạm vi của một hàm. Ở đây mình nói đến từ copy dùng để nhấn mạnh giá trị được truyền vào là một bản sao và lúc này (A) và (B) hoàn toàn độc lập nhau, việc dùng (B) để xử lý trong hàm hoàn toàn không ảnh hưởng gì đến biến ban đầu (A).
2. Truyền tham
chiếu
là làm biến (B) thành một alias
(bí danh)
của (A),
lúc này (A) gần như là (B) và (B) gần như là (A) vì cả 2 đều tham
chiếu đến cùng một đối tượng, mọi thay đổi trên (B)
thực tế cũng là
thay đổi trên (A) (việc tại sao lại nói (A) va (B) lúc này gần như nhau sẽ được giải thích rõ hơn ở phần dưới). Từ đó, sau khi thoát ra khỏi hàm, dữ liệu trên vùng nhớ được (A) tham chiếu tới sẽ bị thay đổi theo các thao tác mà ta đã dùng để thay đổi dữ liệu trên vùng nhớ được (B) tham chiếu tới.
·
Làm sao xác định đâu là tham chiếu, đâu là tham trị trong Java?
Sau một hồi giảng giải dài dòng ở trên, có thể bạn sẽ nói mình khùng khi
mình phát biểu tiếp câu này:
Java chỉ truyền tham
trị, không truyền tham
chiếu.
Thêm một câu khẳng định lại:
Phát biểu trên luôn đúng và không có ngoại lệ!
Mình không khùng
đâu, cái này từng là lầm tưởng của mình trong một thời gian dài và lầm tưởng này nó phổ biến đến mức có thể xếp vào hàng những lầm tưởng phổ biến nhất đối với các lập trình viên Java. Lầm tưởng đó thường được phát biểu như sau:Kiểu
dữ liệu cơ sở được
truyền theo tham trị,
kiểu object được
truyền theo tham chiếu.
Giải thích tiếp Java
chỉ truyền tham
trị, vậy nó truyền tham
trị như thế nào trong
trường hợp với kiểu dữ liệu cơ sở và kiểu
object.
1. Kiểu dữ liệu cơ sở: đối với kiểu dữ liệu cơ sở, Java đơn giản là copy
giá trị của biến để gán vào tham
số. Và như đã nói ở trên,
lúc này biến và tham số sử dụng trong hàm là riêng biệt, khi thoát ra khỏi hàm biến không bị thay đổi giá trị.
2. Kiểu
object: khi truyền một biến có kiểu object vào một hàm thì lúc đó có nghĩa ta đã truyền giá trị của biến đó để sử dụng
trong hàm, chứ không phải truyền đối tượng được biến đó tham chiếu tới. Vậy giá trị của một biến kiểu object là gì??? Nói có vẻ hơi lạ nhưng có thể nói giá trị của biến kiểu object là địa chỉ của object mà biến đó tham chiếu đến đến. Cho nên lúc này việc thay đổi giá trị của biến kiểu
object này bằng cách gán cho một biến kiểu object khác thì object được tham chiếu đến lúc đầu không bị ảnh hưởng, chỉ khi sử dụng các method của chính các object được tham chiếu này thì dữ liệu của object mới được thay đổi sau khi ra khỏi hàm.
Chúc các bạn học tốt!
Góp ý tại mục bình luận bên dưới 💓