Trong quá trình học các kiến thức lập trình Java, chắc chắn không ít bạn nhầm lẫn khái niệm tham trị và tham chiếu. Có rất nhiều bạn có nhận định chưa đúng về hai khái niệm này. Ví dụ như các bạn nói các tham số trong hàm nếu ta truyền kiểu nguyên thuỷ thì đó là tham trị còn nếu truyền kiểu object là tham chiếu. Hôm nay tôi sẽ giải thích cho các bạn hiểu rõ 2 khái niệm này nhé.
1. Gán giá trị
Trước hết chúng ta cần xem lại cách bộ nhớ máy tính lưu trữ các biến và giá trị. Nếu bạn chưa rõ về cách lưu trữ, có thể xem lại bài viết về bộ nhớ tại đây.
- Bộ nhớ chương trình gồm có 2 thành phần chính là địa chỉ bộ nhớ và dữ liệu được lưu trữ trong bộ nhớ đó.
- Ví dụ khi chúng ta gán một biến cho một giá trị như
test = 3
, bộ nhớ cần lưu trữ chữtest
và giá trị3
của nó vào bộ nhớ.
Địa chỉ bộ nhớ | Giá trị ô nhớ |
---|---|
xx1 | test |
xx2 | 3 |
2. Tham trị là gì (pass by value)
Tham trị (Pass by value): nghĩa là chúng ta sẽ clone (tạo ra một giá trị mới bằng cách copy giá trị gốc), và chỉ thao tác giá trị với bản copy. Khi chúng ta thay đổi các giá trị của đối tượng, thì không ảnh hưởng đến giá trị gốc. Pass-by-value được hiểu là khi bạn thay đổi biến trong hàm, thì ngoài hàm sẽ không bị ảnh hưởng.
Hình ảnh minh họa cho tham trị
- Ở ví dụ trên, ta thấy rất rõ giá trị của biến
someValue
. - Trong hàm
main
, chúng ta khai báo nó là giá trị7
. Sau đó ta gọi hàmprocess(int value)
và truyền giá trị7
vào. - Mặc dù ta gán lại giá trị
someValue = 10
, nhưng khi kết thúc hàmprocess
, giá trịsomeValue
là bằng7
chứ không phải là10
. - Bởi vì chúng ta chỉ thao tác với giá trị copy chứ không phải giá trị gốc, nên ta gán
someValue = 10
là gán cho giá trị copy =10
. - Như vậy dù trong hàm
process(int value)
ta có thay đổi giá trị như thế nào đi chăng nữa, thì khi thoát ra khỏi hàm, giá trị gốc vẫn không thay đổi.
Sau khi hàm process(int value)
thực hiện xong nhiệm vụ của mình, thì sẽ bị giải phóng đi, trả lại bộ nhớ cho chương trình, và giá trị clone cũng được giải phóng trả lại bộ nhớ.
3. Truyền tham chiếu
Tham chiếu (Pass by reference): Ngược lại với Pass by value, giá trị gốc sẽ bị thay đổi. Pass-by-reference là khi bạn thay đổi biến trong hàm, cũng làm ngoài hàm bị ảnh hưởng. Nó giống như bạn truyền đúng địa chỉ của biến đó vào hàm.
Trong trường hợp này, hàm process(int &value)
trỏ thẳng tới địa chỉ vùng nhớ nơi lưu giá trị 7
. Như vậy khi ta thay đổi giá trị trong hàm, nó sẽ thay đổi luôn giá trị khác.
4. Tổng kết
Các bạn nên nhớ trong Java là 100% truyền tham trị (passed by value). Chúng ta chỉ clone một giá trị từ giá trị gốc sau đó truyền đi cho các method cần dùng nó. Ta chỉ thay đổi giá trị clone chứ không thay đổi trực tiếp giá trị vùng nhớ của đối tượng gốc.