[Java学习]Java中String的内存机制/String的比较

首先看一个实例:

package test4;

public class Test2 {
	public static void main(String args[]) {
		String s1 = "java";
		String s2 = "java";
		String s3 = new String("java");
		System.out.println(s1 == s2 ? "s1 = s2" : "s1 != s2");
		System.out.println(s1 == s3 ? "s1 = s3" : "s1 != s3");
		System.out.println(s2 == s3 ? "s2 = s3" : "s2 != s3");
		
		//equal fun
		System.out.println(s1.equals(s2) ? "s1 equals to s2" : "s1 doesn't equals to s2");
		System.out.println(s1.equals(s3) ? "s1 equals to s3" : "s1 doesn't equals to s3");
		System.out.println(s2.equals(s3) ? "s2 equals to s3" : "s2 doesn't equals to s3");
	}
}

程序很简单,分别用==和String中的方法equals对3个字符串作了比较。然而结果可能很多人不会想到(特别是学过C++的同学):

s1 = s2
s1 != s3
s2 != s3
s1 equals to s2
s1 equals to s3
s2 equals to s3
下面来解释解释个中缘由~~~

JVM在运行的时候,将内存分为两个部分,一部分是堆,另一部分是栈。堆中存放的是创建的对象,而栈中则是方法的调用过程中的局部变量或者引用。而设计Java字符串对象内存实现的时候,在堆中又开辟了一块很小的内存,称作字符串常量池。专门用来存放特定的字符串对象。

看注解:

package test4;

public class Test2 {
	public static void main(String args[]) {
		String s1 = "java";	//此时"java"被放入字符串常量池中,s1指向之
		String s2 = "java";	//查看字符串常量池,存在"java",s2指向它,并未分配新的字符串
		String s3 = new String("java");
		System.out.println(s1 == s2 ? "s1 = s2" : "s1 != s2");	//作==比较时,实际比较的是两边的对象是否指向同一个引用,这里
		System.out.println(s1 == s3 ? "s1 = s3" : "s1 != s3");	//s1,s2指向同一个常量的引用,而s3被分配在堆中非字符串内存池
		System.out.println(s2 == s3 ? "s2 = s3" : "s2 != s3");	//的区块,从而不和s1/s2相等
		
		//equal fun
		System.out.println(s1.equals(s2) ? "s1 equals to s2" : "s1 doesn't equals to s2");	//equals函数则是比较对象中的具体
		System.out.println(s1.equals(s3) ? "s1 equals to s3" : "s1 doesn't equals to s3");	//也就是具体的字符
		System.out.println(s2.equals(s3) ? "s2 equals to s3" : "s2 doesn't equals to s3");
	}
}
对于C++用户,要特别注意Java的String和C++的STL中封装的String类的差别,C++中支持操作符重载,从而==被重载后实现为比较字符串,而Java的String并没有operator==成员函数,在使用==比较时,并不是调用String中的函数,而是对引用对象的比较。结合上面的注释,应该很容易理解了吧?

Java中这种设计,有两个很可观的优点:其一,实际使用中,字符串比较比其它(比如int,double)等可能会多很多,并且String对象本身可能是十分庞大的,如果能直接用引用对象是否相同来达到比较效果,是可以节约很多资源的。其二,极大地节约了内存的利用率,减少了内存中的冗余。但是,在实际开发中,这种节约大多时候给我们带来的可能是灾难性的结果,甚至影响你本身的编程逻辑。所以,在设计字符串的比较时务必要用equals方法(函数)替换之。^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值