1 回答
TA貢獻1998條經驗 獲得超6個贊
這個問題要分具體的情況的,我下面列舉了三種情況,基本上就都包括了,剩下都可以通過這三種情況類似,先看一下我寫了一段測試結果用的代碼,先看結果,之后我再解釋原因
public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }public class TestRef { public static void main(String[] args) { List<Student> list = new ArrayList<>(); list.add(new Student("zhang",12)); list.add(new Student("liu",13)); System.out.println("list中是普通對象時,修改前"); System.out.println(list); Student stu = list.get(0); stu.setAge(22); System.out.println("list中是普通對象時,修改后"); System.out.println(list); List<Integer> list1 = new ArrayList<>(); list1.add(1); list1.add(2); System.out.println("list1中裝入基本類型時,修改前"); System.out.println(list1); Integer a = list1.get(0); a = new Integer(11); System.out.println("list1中裝入基本類型時,修改后"); System.out.println(list1); List<String> list2 = new ArrayList<>(); list2.add("abc"); list2.add("def"); System.out.println("list2中裝入String時,修改前"); System.out.println(list2); String s = list2.get(0); s = new String("abc_abc"); System.out.println("list2中裝入String時,修改后"); System.out.println(list2); }} |
下面是運行的結果:
list中是普通對象時,修改前[Student [name=zhang, age=12], Student [name=liu, age=13]]list中是普通對象時,修改后[Student [name=zhang, age=22], Student [name=liu, age=13]]list1中裝入基本類型時,修改前[1, 2]list1中裝入基本類型時,修改后[1, 2]list2中裝入String時,修改前[abc, def]list2中裝入String時,修改后[abc, def] |
通過上面的例子我們就會發現,我們在修改Student實例中的年齡是可以修改的,但是在修改基本類型(int,long,short,byte,char,float,double,boolean)和String的時候是不變的。這個是直觀的感受,真是是后面這一半是正確的。
我寫Student這個類的目的就是為了來描述我們自己定義的類會不會變,通過上面的例子我們發現變了,那么什么情況下不變呢,看下面這段代碼:
List<Student> list = new ArrayList<>(); list.add(new Student("zhang",12)); list.add(new Student("liu",13)); System.out.println("list中是普通對象時,修改前"); System.out.println(list); Student stu = list.get(0); //stu.setAge(22); stu = new Student("song",24); System.out.println("list中是普通對象時,修改后"); System.out.println(list); |
這段代碼是沒有修改list中的內容,其實到這里所有的情況就都包括了,很簡單,在Java中傳遞引用,大家經常會把它理解為傳遞C語言中的指針,其實不然,你更應該把他理解為C語言中的傳遞值,這樣就容易解釋一些現象。
以Student這段代碼為例,list.get(0)拿到的是第一個Student實例的值,當我們直接修改這個實例的時候,是不會影響到list中的內容的,如
Student stu = list.get(0);stu = new Student("song",24); |
這種是沒有影響的,但是我們修改返回的這個實例中的屬性的時候的,也就是修改Student中的年齡,姓名等的時候,這個時候是會改變list中的內容的(list中Student的引用的值沒變,但是引用所指向堆中對象具體的屬性改變了)。
也就是下面這種形式會改變的:
Student stu = list.get(0);stu.setAge(22); |
通過這種方式,我們就可以理解基本類型和String的時候為什么不會變了。
添加回答
舉報
