物件引用 方法傳參 值傳遞 引用傳遞 易錯點
阿新 • • 發佈:2018-11-24
Markdown版本筆記 | 我的GitHub首頁 | 我的部落格 | 我的微信 | 我的郵箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | [email protected] |
物件引用 方法傳參 值傳遞 引用傳遞 易錯點
目錄
目錄概念
方法傳遞
案例一
案例二
物件引用
案例一(核心案例)
案例二
案例三
案例四
概念
Java中有沒有引用傳遞?
答:Java中只有按值傳遞,沒有按引用傳遞!
當一個物件被當作引數傳遞到一個方法中後,在此方法中可改變這個物件的屬性,並可返回變化後的結果,那麼這裡到底是值傳遞還是引用傳遞?
答:是值傳遞!
- 不管是原始型別還是引用型別,傳遞的都是【副本】,也可以說是【值】。
- 如果引數型別是【原始型別】,那麼傳過來的就是這個引數的值,如果在函式中改變了副本的值不會改變原始的值。
- 如果引數型別是【引用型別】,那麼傳過來的就是這個引用引數的副本(物件的引用),這個副本存放的是引數的【地址】。如果在函式中沒有改變這個副本的地址,而是改變了地址中的值,那麼在函式內的改變會影響到傳入的引數;如果在函式中改變了副本的地址,如new一個,那麼副本就指向了一個新的地址,此時傳入的引數還是指向原來的地址,所以不會改變引數的值。
方法傳遞
案例一
public class Test { public static void main(String[] args) { int a = 1, b = 2; System.out.println(a + "," + b); swap(a, b); System.out.println(a + "," + b); } public static void swap(int a, int b) { int tem = a; a = b; b = tem; } }
案例二
public class Test {
public static void main(String[] args) {
Person p1 = new Person("1");
Person p2 = new Person("2");
System.out.println(p1 + " " + p2 + "," + p1.name + " " + p2.name);//[email protected] [email protected],1 2
test(p1, p2);
System.out.println(p1 + " " + p2 + "," + p1.name + " " + p2.name);//[email protected] [email protected],2 1
test2(p1, p2);
System.out.println(p1 + " " + p2 + "," + p1.name + " " + p2.name);//[email protected] [email protected],3 4
test3(p1, p2);
System.out.println(p1 + " " + p2 + "," + p1.name + " " + p2.name);//[email protected] [email protected],6 5
test4(p1, p2);
System.out.println(p1 + " " + p2 + "," + p1.name + " " + p2.name);//[email protected] [email protected],6 5
}
private static void test(Person person1, Person person2) {
String temp = person1.name;
person1.name = person2.name;
person2.name = temp;
}
private static void test2(Person person1, Person person2) {
person1.name = "3";
person2.name = "4";
Person person = person1;
person1 = person2;
person2 = person;
}
private static void test3(Person person1, Person person2) {
Person person = person1;
person1 = person2;
person2 = person;
person1.name = "5";
person2.name = "6";
}
private static void test4(Person person1, Person person2) {
person1 = new Person("7");
person2 = new Person("8");
}
}
class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
物件引用
案例一(核心案例)
public class Test {
public static void main(String[] args) {
Work work = new Work();
work.valuse = 1;
Person person = new Person();
person.work = work;
work.valuse = 2;
System.out.println(person.work.valuse); //2
work = new Work();// new 之後 Person 中引用的 Work 就不再是 work 所引用的 Work 了
work.valuse = 3;
System.out.println(person.work.valuse); //2
person.work = work; //將 Person 中引用的 Work 更改為 work 所引用的 Work
System.out.println(person.work.valuse); //3
}
}
class Work {
int valuse;
}
class Person {
Work work;
}
案例二
public class Test {
public static void main(String[] args) {
Work work = new Work();
work.valuse = 1;
ArrayList<Work> list = new ArrayList<Work>();
list.add(work);
Person person = new Person();
person.setList(list);
work.valuse = 2;
System.out.println(person.list.get(0).valuse); //2
person.list.get(0).valuse = 3;
System.out.println(list.get(0).valuse); //3
System.out.println(person.list.get(0).valuse); //3
System.out.println("---------以上並沒有更改引用的物件地址--------");
work = new Work();
work.valuse = 4;
System.out.println(list.get(0).valuse); //3
System.out.println(person.list.get(0).valuse); //3
list.set(0, work);
System.out.println(list.get(0).valuse); //4
System.out.println(person.list.get(0).valuse); //4
}
}
class Work {
int valuse;
}
class Person {
List<Work> list;
public void setList(List<Work> list) {
this.list = list;
}
}
案例三
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
A a = new A();
a.setList(list);
list.add(2);
System.out.println(a.list1.toString()); //[1, 2]
System.out.println(a.list2.toString()); //[1]
System.out.println(a.list3.toString()); //[1]
a.setList(list);
System.out.println(a.list1.toString()); //[1, 2]
System.out.println(a.list2.toString()); //[1, 2]
System.out.println(a.list3.toString()); //[1, 2]
}
}
class A {
public List<Integer> list1 = new ArrayList<Integer>();
public List<Integer> list2 = new ArrayList<Integer>();
public List<Integer> list3 = new ArrayList<Integer>();
public void setList(List<Integer> list) {
this.list1 = list;
this.list2 = new ArrayList<Integer>(list);
list3.clear();
this.list3.addAll(list);
}
}
案例四
public class Test {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();//一個集合
list.add(new Person("包青天", 1, new Work("百度", 1)));//新增資料
String name = list.get(0).name;
int age = list.get(0).age;
Work work = list.get(0).work;
name = "2";//修改資料。注意,這裡的name區域性變數和person物件中的name欄位指向的是不同的例項物件
age = 2;
work = new Work("2", 2);
System.out.println(list.get(0).name + "," + list.get(0).age + "," + list.get(0).work.company + "," + list.get(0).work.time);//包青天,1,百度,1
list.get(0).name = "3";
list.get(0).age = 3;
list.get(0).work.company = "3";
list.get(0).work.time = 3;
System.out.println(list.get(0).name + "," + list.get(0).age + "," + list.get(0).work.company + "," + list.get(0).work.time);//3,3,3,3
Person temPerson = list.get(0);
temPerson.name = "4";
temPerson.age = 4;
Work tempWork = temPerson.work;
tempWork.company = "4";
tempWork.time = 4;
System.out.println(list.get(0).name + "," + list.get(0).age + "," + list.get(0).work.company + "," + list.get(0).work.time);//4,4,4,4
}
}
class Work {
int time;
String company;
public Work(String company, int time) {
this.time = time;
this.company = company;
}
}
class Person {
int age;
String name;
Work work;
public Person(String name, int age, Work work) {
this.age = age;
this.name = name;
this.work = work;
}
}
2017-7-4