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

来源:互联网 发布:ubuntu搭建私有云 编辑:程序博客网 时间:2024/06/09 23:47

首先看一个实例:

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 funSystem.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 = s2s1 != s3s2 != s3s1 equals to s2s1 equals to s3s2 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 funSystem.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
原创粉丝点击