30/09/2018, 20:52

Tham biến và tham chiếu trong java

Mọi người ơi mình cùng thảo luận một chút xíu về tham biến và tham chiếu nha, mình có tìm kiếm trên google về vấn đề này nhưng mình không có thấy chủ đề nào về vấn đề này trong diễn đàn mà chỉ thấy video của Anh Đạt thôi. Nếu như có trùng thì thông cảm cho Em nha Anh. .

Cụ thể như sau, minh có một doạn code sau.

main {
                        Main mMain = new Main();
			HocSinh mHocSinh = new HocSinh();
			mMain.updateInfo(mHocSinh);
}
public void updateInfo(HocSinh hocSinh){
		hocSinh.setTen("Nguyen Van A");
	} ```

nếu code như sau khi mình xuất ra sẽ có kết quả là : Nguyen Van A . ở đây mình biết là nó giống con trỏ trong c++ giữa hocSinh và mHocSinh là 2 thằng cùng trỏ về 1 địa chỉ miền giá trị nào đó. nên thay đổi .

Nhưng bây giờ mình đổi một chút trong updateInfo.

`    public void updateInfo(HocSinh hocSinh){
               HocSinh hocSinh2 = new HocSinh();
	       hocSinh2.setTen("Nguyen Van A");
               hocSinh = hocSinh2();
	} 
`

Kết quả nhận được là : null
CÒn thằng này thì sao. nó cũng trỏ về cùng một miền giá trị với thằng mHocSinh mà tại sao mHocSinh khongo thay đổi trong trường hợp này. ?

Nguyễn Hồng Sơn viết 22:57 ngày 30/09/2018

“Java is always pass-by-value. Unfortunately, they decided to call pointers references, thus confusing newbies. Because those references are passed by value.”

stackoverflow.com

Is Java "pass-by-reference" or "pass-by-value"?

java, methods, parameter-passing, pass-by-reference
asked by user4315 on 08:14PM - 02 Sep 08

Interns viết 23:08 ngày 30/09/2018

nguyen huy hoang viết 23:08 ngày 30/09/2018

ý bạn là pass by value và pass bye refrencer ? trong java chỉ có cái thứ nhất thôi nhé

nguyen huy hoang viết 22:59 ngày 30/09/2018

bạn chú ý 1 điều. khi bạn khai báo tham số truyền vào, bạn nên để tên tham số ở phương thức giống với tham số bạn muốn chuyền vào, bạn để lẫn lôn mhocsinh rồi hocsinh mô tê gì chả ai rảnh ngồi xem từng tí thế đấu, nó là quy tắc khi viết code. code thế này chỉ mình bạn hiểu. về vấn đề bạn hỏi. trong java chỉ có duy nhất 1 kiểu truyền thâm số là truyền bằng giá trị, tức là tạo 1 bản sao rồi đứa vào. khi bản sao thay đổi thì bản gốc không ảnh hưởng. cái này giải thích tại sao lại là null. khi ban gọi phương thức updateinfo rồi truyền vào mhocsinh, 1 bản sao của biến mhocsinh sẽ đươc truyền vào , sau đó biến mhocsinh này thay vì chỉ tới địa chỉ của đối tượng mhocsinh trong bộ nhớ bây giờ nó sẽ chỉ tới đối tương hocsinh2 trong bộ nhớ có thuộc tính tên là nguyễn văn a. tóm lại tất cả những việc bạn làm trong update info là làm với bản sao, chả liên quan gì tới bản chính nen kết qua vẫn là null

cescnghia viết 23:05 ngày 30/09/2018

Theo mình thì pass by value hay pass by reference cái nào cũng đúng, tuỳ theo cách mình suy “nghĩ” như thế nào nữa.
Liên quan tới câu hỏi bạn đặt ra, bạn hãy thử viết hàm swap 2 objects trong java ???

public static void swap(Object o1, Object o2) ???

viết 22:59 ngày 30/09/2018

reference trong Java chính là con trỏ trong C/C++ trừ vụ cộng trừ con trỏ ra thôi. Đừng nhầm lẫn với pass by reference trong C++,

public void updateInfo(HocSinh hocSinh){
    hocSinh.setTen("Nguyen Van A");
} 
...
Main mMain = new Main();
HocSinh mHocSinh = new HocSinh();
mMain.updateInfo(mHocSinh);

tương đương với trong C++ là

void updateInfo(HocSinh* hocSinh){
    hocSinh->setTen("Nguyen Van A");
} 
...
Main* mMain = new Main();
HocSinh* mHocSinh = new HocSinh();
mMain->updateInfo(mHocSinh);

tất cả các object trong Java đều là “con trỏ” trỏ tới object thực sự nằm trên heap. Java sửa con trỏ của C đi 1 tí, hay hạn chế bớt tính năng của con trỏ đi vd như ko cho phép tăng lùi con trỏ nữa, rồi gọi nó là reference…

nếu hiểu như vậy thì dễ dàng thấy là con trỏ truyền vào updateInfo là copy của con trỏ mHocSinh nằm trong main(). Như vậy có gán hocSinh = hocSinh2; thì chỉ có bản copy trỏ tới object khác, chứ bản chính mHocSinh vẫn trỏ tới object cũ.

Java “xóa” bớt dấu * với sửa -> thành . hết cho code dễ đọc, nhưng lại gây khó hiểu cho người học C++ chuyển qua Java ~.~

Tất Huân viết 22:53 ngày 30/09/2018

Trước tiên bạn nên tìm hiểu phạm vi khai báo biến trong java. Trong hàm updateInfo của bạn bạn khai báo biến hocsinh2, biến này chỉ có phạm vi trong dấu ngoặc nhọn chứa nó, tức là sau khi hàm này chạy xong nó sẽ bị hủy. ĐÓ là lý do bạn gán hocsinh = hocsinh2 nhưng in ra thì lại null. Lúc này hocsinh2 bị hủy nên null là điều tất nhiên.

Nguyễn Hải Đăng viết 23:02 ngày 30/09/2018

Chỉ pass by value đúng rồi còn gì. Khai báo Object obj = new Object() thì value của obj là gì?

Tất Huân viết 22:57 ngày 30/09/2018

Vậy ý anh là ko pass được kiểu reference

Nguyễn Hải Đăng viết 22:56 ngày 30/09/2018

Tốt nhất là nói Java truyền biến bằng cách copy như anh đã dạy.
Java lúc nào cũng pass by value. Nhưng người ta lại gọi con trỏtham chiếu cho dễ hiểu, nên dễ gây nhầm lẫn cho những người mới học. Con trỏ trong Java pass-by-value.

Lê Đại Tú viết 23:04 ngày 30/09/2018

hình như sai sai ngược ngược thì phải.

Lê Đại Tú viết 23:05 ngày 30/09/2018

giá trị của obj là địa chỉ của thằng new. k biết vậy phải không ?

Người bị bơ viết 22:57 ngày 30/09/2018
public class test{
            public static void main(String [] agrs){
                Main mMain = new Main();
                HocSinh mHocSinh = new HocSinh();
                mMain.updateInfo(mHocSinh);
                System.out.println(mHocSinh.TenHS);
            }
        }
    public class Main{
        public void updateInfo(HocSinh hocSinh){
            hocSinh.setTen("Nguyen Van A");
        }
    }
    public class HocSinh{
        public String TenHS;
        public void setTen(String Ten){
            TenHS = Ten; 
            System.out.println(TenHS);
        }
    }

Lúc ở phiên bản đầu tiên do chỉ có 1 Object và 2 biến tham chiếu là mHocSinh với hocSinh đều tham chiếu đến cùng 1 Object. Vì vậy setName cho hocSinh thì củng như mHocSinh.
Phiên bản thứ 2 bạn có 2 Object và 3 biến tham chiếu. Đầu tiên lúc đầu thì bạn cho mHocSinh và hocSinh tham chiếu đến cùng Object thứ 1, nhưng sau đó
hocSinh = hocSinh2();
thì hocSinh lại được tham chiếu đến Object thứ 2 vì vậy khi bạn in tên của mHocSinh ra thì nó là null bở vì Object 1 chưa được set, mà bản chỉ set name của Object 2 thôi.
hocSinh2.setTen("Nguyen Van A");

nguyen huy hoang viết 23:07 ngày 30/09/2018

trong java đơn giản là không có truyền tham chiếu

Quân viết 23:09 ngày 30/09/2018

Hiếu đơn giản trong java khi truyền object vào hàm chỉ đơn giản là đặt thêm 1 biệt hiệu cho object thực mà thôi, nếu ta dùng cú pháp

biệt_hiệu = biệt_hieu2;

hoặc

biệt_hiệu = new Object(); 

thì có nghĩa là ta lấy biệt_hiệu gán sang cho object khác

Tom Nguyen viết 23:08 ngày 30/09/2018

Bạn chạy code sẽ thấy rất rõ ràng:

    System.out.println(hocSinh.hashCode());
    System.out.println(hocSinh.getTen());
    System.out.println(hocSinh2.hashCode());
    System.out.println(hocSinh2.getTen());

    hocSinh = hocSinh2;

    System.out.println(hocSinh.hashCode());
    System.out.println(hocSinh.getTen());
    System.out.println(hocSinh2.hashCode());
    System.out.println(hocSinh2.getTen());
Nguyễn Văn Tiến viết 22:55 ngày 30/09/2018

câu trả lời HuansmileTất Huân là chính xác

Thiều Đình Anh viết 23:03 ngày 30/09/2018

Trước tiên bạn nên tìm hiểu phạm vi khai báo biến trong java. Trong hàm updateInfo của bạn bạn khai báo biến hocsinh2, biến này chỉ có phạm vi trong dấu ngoặc nhọn chứa nó, tức là sau khi hàm này chạy xong nó sẽ bị hủy. ĐÓ là lý do bạn gán hocsinh = hocsinh2 nhưng in ra thì lại null. Lúc này hocsinh2 bị hủy nên null là điều tất nhiên.

Bạn giải thích sai bản chất mHocSinh.getTen=NULL vì bản sao của nó được truyền vào hàm và nó ban đầu cùng tham chiếu đến cùng một object nhưng sau bản sao này lại tham chiếu tới đối tượng khai báo trong hàm là hocsinh2 . Mặt khác mHocSinh chưa được set giá trị nên nó vẫn bằng NULL . Ở đây không liên quan gì tới việc đối tượng học sinh 2 bị hủy cả .

Thiều Đình Anh viết 22:54 ngày 30/09/2018

câu trả lời HuansmileTất Huân là chính xác

Chính xác cái gì định hại người à ba . Để nghị admin thêm chức năng dislike chứ không ảnh hưởng tới thế hệ Dev trẻ như mình lớm :v

Quân viết 22:57 ngày 30/09/2018

Chuẩn, sai bét nhè, ai tin và làm theo thì hỏng cả 1 thế hệ

Bài liên quan
0