首先看下面的demo1:
- int a = new Integer(5);
- int b = a;
- b = b + b;
- System.out.println(a); // 5 as expected
- System.out.println(b); // 10 as expected
再看demo2:
- public class SomeObject {
- public String text;
- public SomeObject(String text) {
- this.setText(text);
- }
- public String getText() {
- return text;
- }
- public void setText(String text) {
- this.text = text;
- }
- }
- SomeObject s1 = new SomeObject("first");
- SomeObject s2 = s1;
- s2.setText("second");
- System.out.println(s1.getText()); // second as UNexpected
- System.out.println(s2.getText()); // second as expected
S1爲什麼不是first,二是second,按照上面的邏輯,她應該是first纔對。爲什麼會是這樣呢?
第一個因爲a是基本類型,所以在賦值的時候會把自己copy一份給其他變量,所以執行b=b+b的時候實際是對copy進行操作,所以並不改變原來的a。
第二個是因爲s1,s2,String都是對象類型的。所以在賦值或者傳參的時候都是傳引用的(這裏有不同看法,有人說傳值有人說傳引用,我的理解是java所有都是傳值,但是對象傳的值就是對象的引用)。所以當執行s2=s1的時候就把s1的對象引用賦給了s2,所以對s2的所有操作都會對s1有影響。
如果你希望s1的結果是first,s2的結果是second的話就需要implements Cloneable接口來實現克隆對象。
- public class SomeObject implements Cloneable{
- public String text;
- public SomeObject(String text){
- this.setText(text);
- }
- public String getText() {
- return text;
- }
- public void setText(String text) {
- this.text = text;
- }
- @Override
- protected Object clone(){
- SomeObject so=null;
- try {
- so=(SomeObject)super.clone();
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
- return so;
- }
- }
然後在使用的時候變成:
- public class Test {
- public static void main(String[] args) {
- SomeObject s1 = new SomeObject("first");
- SomeObject s2 = (SomeObject) s1.clone();
- s2.setText("second");
- System.out.println(s1.getText());
- System.out.println(s2.getText());
- }
- }