黑马程序员技术交流社区

标题: 两个什么样的对象才能算是同一个对象? [打印本页]

作者: 张校云    时间: 2011-10-1 13:01
标题: 两个什么样的对象才能算是同一个对象?
两个什么样的对象才算是同一个对象?两个变量名引用的是同一块内存地址,这两个变量就可以算是同一个对象吗?
作者: 丁林    时间: 2011-10-1 13:24
java中的数据类型分为基本数据类型(四类八种)和引用数据类型。(复习一下那个图表!)
java中基本类型的变量是存储在栈中的。引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。

变量是变量,对象是对象。对象是new出来的(存在堆中),new出对象之后才可访问对象的成员变量和成员方法(当然静态成员变量和方法不用new对象也可访问)。不能说“这两个变量就可以算是同一个对象”,混淆了变量和对象的概念,但可以说:“这两个变量指向了同一个对象”。

==操作比较的是两个变量的值是否相等。基本类型的数据很容易理解,对于引用型变量比较的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
==比较的是2个对象的地址,而equals比较的是2个对象的内容。
显然,当equals为true时,==不一定为true。
[ 本帖最后由 丁林 于 2011-10-01  14:11 编辑 ]
作者: 匿名    时间: 2011-10-1 13:32
java程序中测试两个变量是否相等,一种是利用==运算符,另一种是利用equals方法.
         当使用==来判断两个变量是否相等时,如果两个变量是基本数据类型,且都是数值型(不一定要求数据类型严格相同) 则只要两个变量值相等,使用==判断就会返回true
      如果对于两个引用类型的变量,必须他们指向同一个对象时,==判断才会返回true ,==不可比较类型上没有父子关系的两个对象,下面程序使用==来判断两种变量是否相等的结果
public static void main(String[] args)
        {
                int it = 65;
                float fl = 65.0f;
                //将输出true
                System.out.println("65和65.0f是否相等?" + (it == fl));
                char ch = 'A';
                //将输出true
                System.out.println("65和'A'是否相等?" + (it == ch));
                String str1 = new String("hello");
                String str2 = new String("hello");
                //将输出false
                System.out.println("str1和str2是否相等?" + (str1 == str2));
                //将输出true
                System.out.println("str1是否equals str2?" + (str1.equals(str2)));

        }
这个程序的运行结果上面的文件已经解释了
     但是在很多时候,判断两个引用变量是否相等,也希望有一种类似于"值相等"的pandaun规则,并严格要求两个引用变量指向同一个对象,例如在实际应用中,一个集合里面有很多商品,那么我们怎么判断有些商品是同一个呢?我们不需要他们指向同一个对象才任务相等,只要他们的标识符ID相等,即认为他们是相同的商品,黎活明老师的巴巴运动网将的很清楚,
        equals方法是Object类的方法,因此所有的引用变量都可以调用该方法判断是否与其他的引用变量想等,但是这个方法判断两个对象相等的标准语==没有区别,同样要求两个引用变量指向同一个对象才放回true,因此这个Object的equals方法没有实际的意义,在大多数情况下我们需要自定义相等的标准,可以重写equals方法实现.
       另外,很多人说equals方法是判断两个对象的值相等,这个 说法是相等错误的 ,什么叫对象的值呢?对象的值如何相等呢?实际上重写equals方法就是提供自定义相等的标准.
作者: 匿名    时间: 2011-10-1 13:36
当两个对象的哈希值相同并且使用对象的equals方法比较他们的属性值也相同时,那么此时这两个对象就是同一个对象了。
作者: 匿名    时间: 2011-10-1 13:54
对象是在堆中建立的,new一次就在堆中建立一个, 就会被分配到一个内存地址值,两个变量名引用的是同一块内存地址,说明他们引用的是同一个对象
作者: 匿名    时间: 2011-10-1 14:03
java中的数据类型分为基本数据类型(四类八种)和引用数据类型。(复习一下那个图表!)
java中也就有8种基本类型的变量在栈中来存储整数、浮点数、字符和布尔值这四类数据。引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。

变量是变量,对象是对象。对象是new出来的(存在堆中),new出对象之后才可访问对象的成员变量和成员方法(当然静态成员变量和方法不用new对象也可访问)。不能说“这两个变量就可以算是同一个对象”,混淆了变量和对象的概念,但可以说:“这两个变量指向了同一个对象”。
作者: 匿名    时间: 2011-10-1 14:38
我不赞同丁林兄的"equals比较的是2个对象的内容"
如果是这样那么我们重新定义一个Peron对象,如下:
public class Person {
        private String name;
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public Person(String name) {
                this.name = name;
        }
}
然后在实例化两个Person对象
public static void main(String[] args) {
                Person person1 = new Person("张三");
                Person person2 = new Person("张三");
                System.out.println(person1.equals(person2));//返回false
        }
为什么两个对象的内容相等,然而equals方法返回false呢?
因为equals方法是Object的,那么Object中是怎么定义这个equals方法呢?我们打开Object中equals方法的源代码他是如下定义的
    public boolean equals(Object obj) {
        return (this == obj);
    }
也就是说equals和==判断两个对象是否相等,是一回事情,他内部也是通过==符号来判断的,那么这就不存在equals是判断对象内容的说法了.
那么为什么String中实例化两个内容相等的对象 ,用equals方法返回true呢?打开String的源码,我们可以看到:
   public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = count;
            if (n == anotherString.count) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = offset;
                int j = anotherString.offset;
                while (n-- != 0) {
                    if (v1[i++] != v2[j++])
                        return false;
                }
                return true;
            }
        }
        return false;
    }
也就是String覆写了Object的的equals方法,所以才返回true的,那么可以得出结论,在没有对Object类的equals方法做任何手脚的时候equals和==判断标准是一样的,但是可以重新定义两个引用变量是否相等的标准,一切都是你做主.
作者: 匿名    时间: 2011-10-1 22:20
明白了,谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2