首先看下面的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());
- }
- }