A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 燃烧端午 中级黑马   /  2012-6-20 23:44  /  4290 人查看  /  25 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class Judge {

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 String st="abc";
  8.                 String sr="abc";
  9.                 System.out.println(st == sr);//true
  10.                 System.out.println(st.equals(sr));//true
  11.                 String st1 = new String("abc");
  12.                 String sr1 = new String("abc");
  13.                 System.out.println(st1 == sr1);//为什么会是返回false
  14.                 System.out.println(st1.equals(sr1));//true

  15.         }

  16. }
复制代码
关于String类字符串池存放给点指点吧

25 个回复

倒序浏览
public class Judge {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                String st="abc";
                String sr="abc";
                System.out.println(st == sr);//true
                System.out.println(st.equals(sr));//true
                String st1 = new String("abc");
                String sr1 = new String("abc");
                System.out.println(st1 == sr1);//为什么会是返回false//因为st1和sr1是两个对象的引用,所以st1不等于sr1
                System.out.println(st1.equals(sr1));//true//这个equals()是用于比较对象内容的,因为st1和sr1的内容相同所以返回true

        }

}
回复 使用道具 举报
本帖最后由 小张童鞋 于 2012-6-21 00:06 编辑

public class Judge {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                String st="abc";//这里st和sr都直接指向了"abc"字符串,所以==和equals都是true
                String sr="abc";
                System.out.println(st == sr);//true
                System.out.println(st.equals(sr));//true
                String st1 = new String("abc");//在常量池中定义了个"abc"字符串,因为是new出来的,所以会生成一个hash地址值X,变量str指向了这个hash地址值              
                String sr1 = new String("abc");//这里又new了一个新的hash地址值Y,定义变量sr1指向Y         
               System.out.println(st1 == sr1);//为什么会是返回false//X和Y两个hash地址值不一样,当然不能用==了
               System.out.println(st1.equals(sr1));//true//但是两个hash地址值指向的字符串是一样的,就true了

        }

}
回复 使用道具 举报
== 比较的如果是两个对象,则是比较这两个对象的引用地址是否相等,凡是用new 出来对象都是在堆内存的,他们是不可能相等的,
.equals(object)方法比较的是调用者和object的内容是否相等,
而像这样String str = "abe";是直接拿静态数据池里面字符串常量来初始化一个 String 对象的,这是为了避免去new一个对象,用以提高效率的
回复 使用道具 举报
                String st1 = new String("abc")
                String sr1 = new String("abc");
                System.out.println(st1 == sr1);//为什么会是返回false
                System.out.println(st1.equals(sr1));//true
==比较的是两个对象存放的地址,因为都是新new的对象,所以地址自然不一样,因而返回false;而equals方法比较的是字符串的内容,因而返回的为true。
关于字符串池的问题:
字符串池和String类的基本关系:
  Java运行环境有一个字符串池,由String类维护。
  1、执行语句String str="abc"时,首先查看字符串池中是否存在字符串"abc",如果存在则直接将"abc"赋给str,如果不存在则先在字符串池中新建一个字符串"abc",然后再将其赋给str。
  2、执行语句String str=new String("abc")时,不管字符串池中是否存在字符串"abc",直接新建一个字符串"abc"(注意:新建的字符串"abc"不是在字符串池中),然后将其付给str。
而你的问题属于第二种@
回复 使用道具 举报
所有的“==”都是基于指针级的,也就是说只有它们指向的是同一个对象才被认为是相等. 而对于对象值的相等判断则需要重写并使用.equal()方法 在多数常用类,譬如String中,.equal()已经被默认重写为是值相等的了   
回复 使用道具 举报
薄炳鑫 黑马帝 2012-6-21 00:13:15
7#
先给你解释一下==和equals比较的内容
==比较的是两个对象引用的地址值,当两个对象引用都指向同一个对象时就会出现相等。
equals比较的是两个对象的hash值,而且String的hash值是通过字符串内容生成的,所以相同的字符串会出现相等的hash值。
  1. public class Judge {

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 String st="abc";
  8.                 String sr="abc";//这里的两个对象引用指向同一个abc
  9.                 System.out.println(st == sr);//true
  10.                 System.out.println(st.equals(sr));//true
  11.                 String st1 = new String("abc");
  12.                 String sr1 = new String("abc");
  13.                 System.out.println(st1 == sr1);//因为上面创建对象的两个方法,创建了两个不同的对象,使得对象引用有了两个不同的地址值。
  14.                 System.out.println(st1.equals(sr1));//根据equals方法比较的字符串hash值相同,所以两个值相等。

  15.         }

  16. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
职业规划-刘倩老师 + 1 赞一个!

查看全部评分

回复 使用道具 举报
String str = "abc";
String str = new String("abc");
两种的形式来创建,用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而String str = "abc";是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true ,可以看出str1和str2是指向同一个对象的。
String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false ,用new的方式是生成不同的对象。每一次生成一个。
        因此用String str1 = "abc"; 方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
回复 使用道具 举报
equals检测的是两对象是否相等,即他们的内容是否相等
==比较的是基本数据类型或者引用,或者说他们指向内存的地址。

s1 = new String("java"); //创建的是字符串对象
s1.equals("java"); //返回true  比较s1对象的内容是不是"java”.
s1 == "java" //返回false 比较s1对象在内存中存放的地址和"java”的地址是不是同一个地址
//如果
s1 = "java"; //注意这种赋值方式和上面的区别
s1 == "java" //返回true

回复 使用道具 举报
                      String s1 = "Monday";     
            String s2 = new String("Monday");
            System.out.println(s1==s2);
            System.out.println(s1.equals(s2));
== 永远比较的是地址
equals 比较的是内容是片面的: Object类equals比较的还是地址;String首先比较地址,如果地址相同则返回true ,其次在比较内容
回复 使用道具 举报
public class Judge {


        /**

         * @param args

         */

        public static void main(String[] args) {

                // TODO Auto-generated method stub

                String st="abc";

                String sr="abc";

                System.out.println(st == sr);//true

                System.out.println(st.equals(sr));//true

                String st1 = new String("abc");

                String sr1 = new String("abc");

                System.out.println(st1 == sr1);//为什么会是返回false   

                System.out.println(st1.equals(sr1));//true


        }


}
步骤:
1) 栈中分别开辟一块空间存放引用str1,sr1;
2) String sr1 = new String("abc"); 堆中开辟一块新空间存放另外一个(不同于st1所指)新建的String对象;
3) 引用sr1指向另外新建的那个String对象 ;
4) st1和str1指向堆中不同的String对象,地址也不相同,输出为false;
用equals方法用于判断字符串是否相同

回复 使用道具 举报
首先是数据保存位置


栈(heap)内存中存放基本类型,引用,局部变量;
堆(stack)内存中存放new出来的对象;
方法区(共享区,数据区)中存放静态变量,字符串常量,方法代码。方法区的代码被调用时,将在栈中开辟空间。运行完后,栈中的空间被释放。


对于==  

如果是基本数据类型,那么它们是存在方法区中。方法区中只允许有一个相同的数据,如果多次用到同一个数据类型,则会指向方法区中相同的地址。

正是因为如此,才会说  对于基本数据类型,直接盘对是否相等。例如:

String a="asd";

String b=new String("asd") 这样,物理地址一样,==返回true,但是按照最开始的理解,用equals()方法应该也返回true了。但是结果是返回false.

这是为什么呢?因为.equals()在比较的时候,首先要比较的是两个是不是一个类型,然后再比较物理地址是不是一样,必须两者都满足,才返回true.
回复 使用道具 举报
解释一下==号,他比较的是一个对象在内存中的地址值,
比如2个字符串对象
String s1 = new String("str");
String s2 = new String("str");
如果用==号比较,会返回false,因为创建了两个对象,他们在内存中地址的位置是不一样的。

equals的情况比较复杂,它是java.lang.Object类中的一个方法。因为java中所有的类都默认继承于Object,所以所有的类都有这个方法。

在Object类源码中是这样写的。
public boolean equals(Object obj) {
return (this == obj);
}
他同样使用==号进行内存地址的比较。但是许多java类中都重写了这个方法,比如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里的方法,如果==号比较不相等,还会进行一下值的比较。
所以equals方法具体的作用要看当前的那个类是如何实现重写父类中该方法的。如果没有重写该方法,那么他和==号等价。
回复 使用道具 举报
我总结了一下~==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
如果两个都是基本数据类型比较:
那么都在栈中存储,只需要比较是否等值就可以了
如果两个都是引用数据类型比较:
那么都在堆中存储,在堆中存储的话就要看对象指向的内容是否一致来分析了,像楼楼的问题中创建了两个对象,所以两个对象存在栈中的地址肯定不一样,所以用==返回False,但是又因为对象都指向“abc”,即对象的内容一样所以equals比较的话返回True
关于String类
使用String str = "abc";的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象
回复 使用道具 举报
熊雪莲 发表于 2012-6-21 15:05
我总结了一下~==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否 ...

你恰恰说反了,你弄混了吧?
回复 使用道具 举报
public class Judge {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                String st="abc";
                String sr="abc";
                System.out.println(st == sr);//true
                System.out.println(st.equals(sr));//true
                String st1 = new String("abc");
                String sr1 = new String("abc");
                System.out.println(st1 == sr1);//为什么会是返回false ,因为这里 ==  是用来比较两个对象 即 st1 和st2 的引用是不是相同,new产生两个对象,返回的结果肯定是false             
     System.out.println(st1.equals(sr1));//,在复写掉Object中的equals()之前呢,他的作用和 == 是一样一样的,复写掉之后,他的作用就成了比较两个对象的内容是不是一样的啦,结果都是“abc”,所以返回true

        }

}
回复 使用道具 举报
"=="比较的是对象
equals()比较的是内容
String st1 = new String("abc");
String sr1 = new String("abc");
System.out.println(st1 == sr1);//此句中str1和str2在栈内存中开辟了两个空间,指向的地址值不同,所以输出false
System.out.println(st1.equals(sr1));//此句中str1和str2包含的内容都是abc,内容相等,所以输出true

回复 使用道具 举报
还有补充一点,equals()是复写Object中的方法,它建立了本对象自己比较相同的特有方式,比较的是数值是否相同
回复 使用道具 举报
作为一个Java的初学者,刚开始学习时,我对于他们一直是出于很模糊的认识,没有清醒的认识它们本质上的区别

  在JAVA中,==与equals都有比较判断对象是否相等的作用,但具体用法却并不相同。==是运算符号,而equals则属于方法。

  当==两边的对象属于基本类型时,==的作用仅是比较对象的值是否相等,如果相等返回true,否则返回false;当两边的对象属于引用数据类型时,==的作用是判断对象的内存地址是否一致,如果同时指向同一地址,则返回true,否则返回false.

  equals两边对象只能属于引用数据类型,因为equals是方法,所以它是如何具体判断对象是否相等是根据程序而定的,equals是属于object类,默认是判断内存地址是否相同,但在object的子类中可以重写equals方法,如在String类中只是比较对象内容是否一致,一致则返回true,否则返回false

  比如: String s1="abc";

  String s2="abc";

  s1.equals(s2) 是true 因为equals比较的是对象的内容

  而 s1==s2 是false 因为当两边的对象属于引用数据类型时,==的作用是判断对象的内存地址是否相同,s1和s2创建了不同的对象,所以内存地址肯定不同。
回复 使用道具 举报
String s1="abc";
String s2="abc";
以上两句话表示s1和s2都指向了堆内存中的"abc"
因为"=="比较的是对象的地址值,所以 s1==s2 为true

那为什么
String s3=new String("java");
s3=="java" 的结果却为false,难道是这句话先是在堆内存中又创建了一个String对象,其值为java吗?
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马