《Java 编程思想》-第3章 操作符 笔记

来源:互联网 发布:广联达软件教学 编辑:程序博客网 时间:2024/06/01 07:18

第3章 操作符

一,别名现象与对象引用
int a = b 表示将b的值赋给a,之后a和b是两个独立的部分。但是在为对象进行“赋值”的时候,情况却发生了变化。对一个对象进行操作时,我们真正操作的是对象的引用。所以倘若“将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方。Object a = b 则a 将被 b引用覆盖,a和b指向b所指的对象。
如下代码

public class Test{    private int level;    private String name;    public void add()    {        level++;    }    public void  Subtract(Test t)    {        t.level--;    }    public String getLevel()    {        return name+":"+level;    }    public Test(String name ,int level)    {        this.name=name;        this.level=level;    }    public static void main(String[] args) {    Test t1=new Test("t1",10);    Test t3=new Test("t3",30);    Test t4=new Test("t4",40);    Test t2=new Test("t2",20);    t2=t1;    t2.add();    System.out.println(t1.getLevel()+"|address:"+t1.toString());    System.out.println(t2.getLevel()+"|address:"+t2.toString());    t3.Subtract(t4);    System.out.println(t3.getLevel()+"|address:"+t3.toString());    System.out.println(t4.getLevel()+"|address:"+t4.toString());    }}

运行结果:
这里写图片描述
表达式t2=t1;将t1在内存中的引用传递给t2,原来t2的引用被覆盖。t1和t2是对同一内存空间的引用,所以t2的level加1后,t1的level也加1改变。t3.Subtract(t4);说明以对象作为函数参数可以实现对该对象进行操作。在上面两个例子中,其实都是Java中的别名现象,只不过表现形式不同,他们都是在对同一个引用进行操作。我们可能并不希望第一个例子中t1中的level也增加了,
在java中有接口Cloneable,实现它方法clone()。然后将 Person p2 = p1替换成Test t2 = t1.clone()即可。
代码如下:

public class Test implements Cloneable{    private int level;    private String name;    public void add()    {        level++;    }    public void  Subtract(Test t)    {        t.level--;    }    public String getLevel()    {        return name+":"+level;    }    public Test(String name ,int level)    {        this.name=name;        this.level=level;    }    public Test clone(){        Test object = null;        try {        object =  (Test) super.clone();        }         catch (CloneNotSupportedException e) {        e.printStackTrace();        }        return object;}    public static void main(String[] args) {    Test t1=new Test("t1",10);    Test t3=new Test("t3",30);    Test t4=new Test("t4",40);    //Test t2=new Test("t2",20);    Test t2=t1.clone();    t2.add();    System.out.println(t1.getLevel()+"|address:"+t1.toString());    System.out.println(t2.getLevel()+"|address:"+t2.toString());    t3.Subtract(t4);    System.out.println(t3.getLevel()+"|address:"+t3.toString());    System.out.println(t4.getLevel()+"|address:"+t4.toString());    }}

运行结果
这里写图片描述
clone()方法是在内存中再次给t2划分出一块资源,t1与t2各自拥有一个引用,此时的p1和p2是在内存中是两个完全独立的部分,谁都不能对另一个对象进行任何操作,但是这两个对象中的值又是完全相同的(刚刚调用clone方法后),包括name,level等其他变量或者方法,

二,“==”与“equals()”
观察下面代码

public class Test1 {    int t;    public static void main(String[] args) {        int a=2;        int b=2;        Integer n1=new Integer(3);        Integer n2=new Integer(3);        Test1 t1=new Test1();        Test1 t2=new Test1();        t1.t=t2.t=7;        System.out.println(a==b);        System.out.println(n1==n2);        System.out.println(n1.equals(n2));        System.out.println(t1==t2);        System.out.println(t1.equals(t2));    }}

结果:
true
false
true
false
false
“==”对于基本数据类型,判断两个变量的值是否相等,“equal”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。
因为对象变量的存储的是对象在内存中的路径,即内存地址。所以用“==”比较时,即使 对象的值相等,但是他们的内存地址不同,所以==的结果为false。总之: “==”比较的是值【变量(栈)内存中存放的对象的(堆)内存地址】 equals()用于比较两个对象的值是否相同【不是比地址】
【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==”不同,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。
Integer类·的equals方法
这里写图片描述
Object类的equals方法
这里写图片描述

0 0
原创粉丝点击