如果:
string s1=new String("Hello");
string s2=new String("Hello");
则(s1==s2)=false
而:
string s1="Hello";
string s2="Hello";
则(s1==s2)=true;
因为他们指向的同一个对象。
通过上例,可以看出,字符串在初始化时:
String s1="Hello";
String s2="Hello"; //s1与s2是指向同一对象,无论用“equals”还是“==”,其结果都是相等,结果都为true
与
String s1=new String("Hello");
String s1=new String("Hello"); //s1与s2是不同的对象,用“equals”为true,而用“==”为false
是不同的。
如果把其他变量的值赋给s1和s2,即使内容相同,由于不是指向同一个对象,也会返回false。所以建议使用equals(),因为equals比较的才是真正的内容!
上述==和equal都相等
上述== 不相同 。equal相等。不同的对象,相当于不同的字符串申请方式。
打开String类的源码发现这是一个本地方法,定义如下:
public native String intern();
文档告诉我们该方法返回一个字符串对象的内部化引用:
由String类维护一个初始为空的字符串的对象池,当intern方法被调用时,如果对象池中已经包含这一个相等的字符串对象则返回对象池中的实例,否则添加字符串到对象池并返回该字符串的引用。
从程序的角度上怎么来看这个方法呢
我们假设有两个字符串s1,s2,当s1.equals(s2)时,s1.intern()==s2.intern(),
也就是说这两个字符串在内存中使用的是同一个实例。
Java语言规范中定义了字符串文字以及更一般的常量表达式的值的字符串是被内部化的,以便它们共享同一个实例。我们试验一下下面代码
String s1 = "你好,Java自由人";
String s2 = "你好," + "Java自由人";
System.out.println(s1==s2);
System.out.println(s1.intern()==s2.intern());
这段代码将打印两个true,也就是说字符串s1和s2是共享同一个实例。不过前提是尽管使用了表达式,但是表达式中必须都是常量。
当然我现在还想不出这个方法到底有什么用,不过算是对Java虚拟机内部组织结构的一些了解,
同时了解这个处理机制也可以让我们在用到字符串常量的时候了解如何节省这些字符串所占用的内存。
很奇怪的是intern这个方法居然在JBuilder 2005上被告知是一个未定义的方法,在Eclipse中表现很正常。
string s1=new String("Hello");
string s2=new String("Hello");
则(s1==s2)=false
而:
string s1="Hello";
string s2="Hello";
则(s1==s2)=true;
因为他们指向的同一个对象。
通过上例,可以看出,字符串在初始化时:
String s1="Hello";
String s2="Hello"; //s1与s2是指向同一对象,无论用“equals”还是“==”,其结果都是相等,结果都为true
与
String s1=new String("Hello");
String s1=new String("Hello"); //s1与s2是不同的对象,用“equals”为true,而用“==”为false
是不同的。
如果把其他变量的值赋给s1和s2,即使内容相同,由于不是指向同一个对象,也会返回false。所以建议使用equals(),因为equals比较的才是真正的内容!
String str="hello";
if(str=="hello")
System.out.print("==");
else System.out.print("!=");
上述==和equal都相等
String str=new String("hello");
if(str.equals("hello"))
System.out.print("==");
else System.out.print("!=");
上述== 不相同 。equal相等。不同的对象,相当于不同的字符串申请方式。
String str=new String("hello");
str=str.intern();
if(str=="hello")
System.out.print("==");
//返回true
打开String类的源码发现这是一个本地方法,定义如下:
public native String intern();
文档告诉我们该方法返回一个字符串对象的内部化引用:
由String类维护一个初始为空的字符串的对象池,当intern方法被调用时,如果对象池中已经包含这一个相等的字符串对象则返回对象池中的实例,否则添加字符串到对象池并返回该字符串的引用。
从程序的角度上怎么来看这个方法呢
我们假设有两个字符串s1,s2,当s1.equals(s2)时,s1.intern()==s2.intern(),
也就是说这两个字符串在内存中使用的是同一个实例。
Java语言规范中定义了字符串文字以及更一般的常量表达式的值的字符串是被内部化的,以便它们共享同一个实例。我们试验一下下面代码
String s1 = "你好,Java自由人";
String s2 = "你好," + "Java自由人";
System.out.println(s1==s2);
System.out.println(s1.intern()==s2.intern());
这段代码将打印两个true,也就是说字符串s1和s2是共享同一个实例。不过前提是尽管使用了表达式,但是表达式中必须都是常量。
当然我现在还想不出这个方法到底有什么用,不过算是对Java虚拟机内部组织结构的一些了解,
同时了解这个处理机制也可以让我们在用到字符串常量的时候了解如何节省这些字符串所占用的内存。
很奇怪的是intern这个方法居然在JBuilder 2005上被告知是一个未定义的方法,在Eclipse中表现很正常。