• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    5年前 (2013-08-12)  java 评论关闭  11 
    文章评分 0 次,平均分 0.0

    值类型是存储在内存的栈中,而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
    ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。u=1937730055,2226876815&fm=21&gp=0
    equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

    ==比较的是2个对象的地址,而equals比较的是2个对象的内容。
    显然,当equalstrue时,==不一定为true

    一、String中的equals==
    1

    public class TestString {
    	     public static void main(String[] args) {         
    		String s1 = "Monday";         
    		String s2 = "Monday";     
    		}
    	}
    

    上面这段程序中,到底有几个对象呢?
    来检测一下吧,稍微改动一下程序

    public class TestString {     
    	public static void main(String[] args) {         
    	String s1 = "Monday";         
    	String s2 = "Monday";         
    	if (s1 == s2)             
    		System.out.println("s1 == s2");         
    	else             
    		System.out.println("s1 != s2");     
    		}
    }

    编译并运行程序,输出:s1 == s2
    说明:s1 与 s2 引用同一个 String 对象 -- "Monday"!

    2.
    再稍微改动一下程序,会有更奇怪的发现:

    public class TestString {     
    	public static void main(String[] args) {         
    	String s1 = "Monday";         
    	String s2 = new String("Monday");         
    	if (s1 == s2)             
    		System.out.println("s1 == s2");         
    	else             
    		System.out.println("s1 != s2");         
    	if (s1.equals(s2))             
    		System.out.println("s1 equals s2");         
    	else             
    		System.out.println("s1 not equals s2");     
    	}
    }

    我们将 s2 用 new 操作符创建
    程序输出:
    s1 != s2
    s1 equals s2
    说明:s1 s2分别引用了两个"Monday"String对象

    3. 字符串缓冲池

    原来,程序在运行的时候会创建一个字符串缓冲池
    当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会
    在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被
    放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
    将 s2 引用 s1 所引用的对象"Monday"
    第二段程序中,使用了 new 操作符,他明白的告诉程序:
    "我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创
    建在内存中。他们的值相同,但是位置不同,一个在池中游泳
    一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?
    4.
    再次更改程序:

    public class TestString {     
    	public static void main(String[] args) {         
    	String s1 = "Monday";         
    	String s2 = new String("Monday");         
    	s2 = s2.intern();         
    	if (s1 == s2)             
    		System.out.println("s1 == s2");         
    	else             
    		System.out.println("s1 != s2");         
    	if (s1.equals(s2))             
    		System.out.println("s1 equals s2");         
    	else             
    		System.out.println("s1 not equals s2");     
    	}
    }

    这次加入:s2 = s2.intern();
    程序输出:
    s1 == s2
    s1 equals s2

    原来,(java.lang.Stringintern()方法 
    "abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作: 
    检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。

    更好的办法:
    把所有的Stringintern()到缓冲池去吧最好在用到new的时候就进行这个操作String s2 = new String("Monday").intern();然后就可以用==比较两个字符串的值了

     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/2264.html

    关于
    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享