30/09/2018, 20:20
JAVA pass by value or pass by reference :D chủ đề muôn thuở
Trước khi kết thành kim đan có 1 tâm ma mà anh em tu “tay” vướng phải là pass by value hay pass by reference
package javaapplication1;
import java.util.Scanner;
public class JavaApplication1 {
public static class sn{
private int v;
public sn(int i){v=i;}
public sn(){}
public int getv(){return v;}
public void setv(int i){v=i;}
}
public static void changei5i6_v2(sn i,sn j){
sn k=i;
i=j;j=k;
i.setv(3);
j.setv(4);
}
public static void changei5i6(sn i,sn j){
sn k=new sn();
k=i;
i=j;j=k;
}
public static void changei4(sn i){
sn j= new sn();
j.v=i.v;
j.setv(2);
}
public static void changei3(sn i){
sn j=new sn();
j=i;
j.setv(2);
}
public static void changei2(sn i){
i.setv(2);
}
public static void changei1(int i){
i=2;
}
public static void main(String[] args) {
//int
int i1=0;
changei1(i1);
System.out.println(i1);
//obj
sn i2= new sn(0);
changei2(i2);
System.out.println(i2.getv());
//obj i3
sn i3= new sn(0);
changei3(i3);
System.out.println(i3.getv());
//obj i4
sn i4= new sn(0);
changei4(i4);
System.out.println(i4.getv());
//obj i5 i6
sn i5=new sn(1);
sn i6= new sn(2);
changei5i6(i5,i6);
System.out.println(i5.getv()+";"+i6.getv());
//obj i5 i6 v2
changei5i6_v2(i5,i6);
System.out.println(i5.getv()+";"+i6.getv());
}
}
Đoán kết quả nào
Bài liên quan
java là pass reference by value do đó kết quả sẽ là
chưa test lại
Java bỏ khái niệm con trỏ nên tất cả đều là pass by value. Tuy nhiên, có 1 điều có thể confuse với những người mới học (khái niệm reference trong java), ví dụ như dưới đây
Lý do rất đơn giản: Java gọi các pointer reference, do đó việc pass các reference này theo value.
Thế nên phải gọi Java là
PASS BY VALUE OF REFERENCE (truyền theo giá trị của tham chiếu)
Em có 1 vấn đề đó là
Em có 1 obj abc
Trong hàm
private void mainwork(){
xuli(abc);
}
private voi xuli(obj a){
// ở đây em muốn xử lí obj a mà ko không làm thay đổi giá trị của obj abc ban đầu
//thì có cách nào ko ạ , đối với List thì em hay dùng
// List b= new arraylist(a); hoặc addall
// còn đối với obj thì em toàn phải gán tuần tự từng value có cách nào copy ra luôn k ạ
}
Tìm hiều về imuable trong Java, giống như Long, String,Interger. để làm được (tạo immuable object ) điểu này có thể khai báo final class.
Có 1 số cách làm:
Trong thư viện org.apache.commons.lang.SerializationUtils cũng cung cấp 1 function dành cho deep clone
Cảm ơn 2 anh @Phan_Hoang @nguyenhuuca
vì sao lại tạo ra deep copy khi đã có shallow copy?
What is the difference between a deep copy and a shallow copy?
bác giải thích cho e cái khác giữa changei5i6 và changei5i6v2 được k? cứ nghĩ là 2;1 mà k phải
bạn có thể xem diễn giải bằng hình như sau cho dễ hiểu
https://drive.google.com/open?id=0B8pezEwuUWSbNWVWbmxldnRhX28
e hiểu rồi
nhưng vẫn đề này thì s ạ Tham biến và tham chiếu trong java
Như hình minh họa mình up ở trên, phép gán objA = objB không phải là objA trỏ đến objB mà objA sẽ trỏ đến vị trí mà objB đang trỏ đến. Tương tự, việc bạn truyền tham số vào hàm thực chất là tạo 1 obj mới trỏ tới giá trị mà obj truyền vào đang trỏ tới,
PS: mọi phép gán objA = objB đều sẽ khiến objA từ bỏ reference tới giá trị mà nó đang trỏ tới, đồng thời reference tới giá trị mà objB đang trỏ tới
ở đây mình hiểu tnay,sai ở đâu sửa giúp mình nhé.
HocSinh hocSinh2 = new HocSinh(); //hocSinh2 trỏ tới 1 HocSinh
hocSinh2.setTen(“Nguyen Van A”); // hocSinh2 đã sets tên đối tượng n trỏ tới thành “Nguyen Van A”
hocSinh = hocSinh2(); //hocSinh trỏ tới cùng đối tượng hocSinh2 đang trỏ => cũng có tên là “Nguyen Van A”
vậy mà lại in ra null
Cái mà bạn in ra là mHocSinh đúng không, ngay thời điểm thực hiện câu lệnh hocSinh = hocSinh2 thì hocSinh và mHocSinh đã là 2 người xa lạ, do đó dữ liệu mà hocSinh và mHocSinh trỏ tới là khác nhau. bạn nên lưu ý là cái được truyền vào hàm k phải là mHocSinh mà chỉ là địa chỉ nơi mà mHocSinh đang trỏ tới thôi
Mình thì vẫn giữ nguyên quan điểm : Khi kết thúc hàm thì Hocsinh2 bị hủy (Bạn xem lại phạm vi biến trong java sẽ rõ) nên Hocsinh trỏ đến Hocsinh2 sẽ null
mình hiểu rồi,có phải là thế này k: thực chất khi truyền mhocsinh vào chỉ là cho hocsinh trỏ tới mhocsinh nơi mhocsinh trỏ tới. Rồi gán hocsinh = hocsinh2 thì chỉ làm hocsinh trỏ đến cùng nơi với hocsinh2.
CHỨ KHÔNG LÀM THAY ĐỔI GÌ ĐẾN MHOCSINH
Chính xác là vậy,…
Điều này là k đúng, 1 biến hay nói đúng hơn là 1 object có thể tồn tại lâu hơn bạn tưởng nhiều, lí thuyết là ra khỏi hàm thì biến bị hủy tuy nhiên thực tế thì không phải vậy, thời gian sống thực tế phụ thuộc vào việc bộ dọn rác của jvm đã dọn tới biến đó hay chưa hay theo 1 cách hiểu khác là đã bị thu hồi lại hay chưa. Bạn có thể tìm đọc các tài liệu liên quan tới cách làm việc của bộ dọn rác trên jvm và các máy ảo cùng họ để hiểu thêm.
Ở đây lí do khi ra khỏi hàm bị null là do biến mHocsinh ở ngoài và biến hocsinh tham số hàm là 2 biến khác nhau đang cùng trỏ tới 1 miền dữ liệu, việc gán biến hocsinh2 cho biến hocsinh thực chất chỉ là thay đổi miền giá trị mà biến hocsinh đang trỏ tới sang miền giá trị mà hocsinh2 đang trỏ tới, điều này chẳng ảnh hưởng gì đến vị trí mà biến mhocsinh ở ngoài hàm đang trỏ tới cả