1.1. String a = “goodluck”理解
文字解释:
Stringa = "goodluck";//先在栈中创建一个String类型的对象引用变量a,然后去常量池中找是否有“goodluck”字符串,
// 如果没有就将“goodluck”放入常量池中,如果有了就直接将a指向“goodluck”,在这里产生一个对象"goodluck",产生一个引用a
Stringb = "goodluck";//先在栈中创建一个String类型对象引用变量b,然后去常量池中找是否有“goodluck”字符串,
// 如果有了就直接将b指向“goodluck”,在这里产生一个引用a,没有再一次产生队象“goodluck”
图解:
代码:
package javabase;
public class StringTest2 {
public static void main(String[] args) {
String a = "goodluck";
String b = "goodluck";
System.out.println(a == b);
System.out.println(a.equals(b));
System.out.println(a.intern() == b.intern());
}
}
运行结果:
true
true
true
1.2.String a = new String(“goodluck”)理解
文字解释:
String newA =new String("goodluck");//先在栈中创建一个String类型的引用对象变量newA,然后new()操作,会在heap堆中
// 创建一个新的对象“goodluck”,并将newA指向堆中的“gooluck”,同时检查String的常量池中是否有对象“goodluck”,如果没有也
// 产生一个对象“gooluck”,如果有则不产生,因为这里之前已经在String常量池中有了,所以不会再进行创建。
String newB = new String("goodluck");//因为只要有new()就会在堆中创建新的对象,栈中的引用指向堆中。这一句的执行,
图解:
代码:
package javabase;
public class StringTest2 {
public static void main(String[]args) {
String newA =new String("goodluck");//先在栈中创建一个String类型的引用对象变量newA,然后new()操作,会在heap堆中
// 创建一个新的对象“goodluck”,并将newA指向堆中的“gooluck”,同时检查String的常量池中是否有对象“goodluck”,如果没有也
// 产生一个对象“gooluck”,如果有则不产生,因为这里之前已经在String常量池中有了,所以不会再进行创建。
String newB =new String("goodluck");//因为只要有new()就会在堆中创建新的对象,栈中的引用指向堆中。这一句的执行,
// 同上一句。
// 在常量池中创建"goodluck"
System.out.println(newA.intern());
System.out.println(newA ==newB);
System.out.println(newA.equals(newB));
System.out.println(newA.intern()== newB.intern());
}
}
运行结果:
goodluck
false
true
true
1.3.String中== 与equals理解
package javabase;
public class StringTest {
public static void main(String[] args){
String a = "goodluck";
String b = "goodluck";
System.out.println(a == b);
System.out.println(a.equals(b));
String newA = new String("goodluck");
String newB = new String("goodluck");
String c = "good";
String d = "luck";
System.out.println(c+d);
System.out.println(a == c+d);
System.out.println(a =="good"+"luck");
System.out.println(a.intern());
System.out.println(a.intern()==b.intern());
System.out.println(a.intern()==newA.intern());
System.out.println(a.intern()==newB.intern());
System.out.println(a == newA);
System.out.println(a.equals(newA));
System.out.println(newB == newA);
System.out.println(newB.equals(newA));
}
}
1.3.1. 概述:
(1)==可用于基本类型和引用类型:当用于基本类型时候,是比较值是否相同;当用于引用类型的时候,是比较对象是否相同。
(2)对于String a = “a”; Integer b = 1;这种类型的特有对象创建方式,==的时候值是相同的。
(3).基本类型没有equals方法,equals只比较值(对象中的内容)是否相同(相同返回true)。
(4)一个类如果没有定义equals方法,它将默认继承Object中的equals方法,返回值与==方法相同。
1.3.2. 详述:
(1)==和equals的实质。
在JAVA中利用"=="比较变量时,系统使用变量在"栈"中所存的值作为比较的依据。
基本数据类型在"栈"中存的是其内容值,而对象类型在"栈"中存的是地址,这些地址指向"堆"中的对象。java.lang包中的Object类有publicboolean equals(Object obj)方法,它比较两个对象是否相等。其它对象的equals方法仅当被比较的两个引用指向的对象内容相同时,对象的equals()方法返回true。总之,"=="和"!="比较的是地址.也可认为"=="和"!="比较的是对象句柄;而equals()比较的是对象内容.或者说,,"=="和"!="比较的是"栈"中的内容,而equals()比较的是"堆"中的内容.
(2)==操作符。专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相当,只能用==操作符。
Java的基本数据类型为(char,byte,short,int,long,float,double,boolean)。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(对内存),变量本身也占用一块内存,
例如Object obj= new Object()变量obj是一个内存,new Object()是一个内存,此时,
变量所对应的内存中存储的数据就是对象占用的那块内存的首地址。对于指向对象内存的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
(3)如果一个类没有定义equals方法。它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this==o;
}
这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,
也是比较两个变量指向的对象是否是同一个对象,这时候使用equals和使用==会得到同样的结果,
如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,
那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可以认为两个对象的内容是相同的。
1.4. String中intern()方法理解
intern是一个native的方法,但按照其文档解释,应该是JVM维护了一个当前进程曾经出现过的字符串的hash表,在调用intern时,会查询该表。如果已经存在,则直接返回对该String的引用;如果没有,则创建一个,并加入到hash中。
使用 String a = “goodluck”;这种不用new 来进行创建的String自动会调用intern()方法,
另外,如果使用字面量(literal)来定义字符串,则自动会调用intern,从而减少内存占用。
package javabase;
public class StringTest2 {
public static void main(String[]args) {
String newA =new String("goodluck").intern();
String newB =new String("goodluck").intern();
// String newB =newA;
System.out.println(newA.intern());
System.out.println(newA ==newB);
System.out.println(newA.equals(newB));
System.out.println(newA.intern()== newB.intern());
}
}
运行结果:
goodluck
true
true
true
package javabase;
public class StringTest2 {
public static void main(String[]args) {
String newA =new String("goodluck");
// String newB =new String("goodluck").intern();
String newB =newA;
System.out.println(newA.intern());
System.out.println(newA ==newB);
System.out.println(newA.equals(newB));
System.out.println(newA.intern()== newB.intern());
}
}
运行结果:
goodluck
true
true
true
代码: String newA = new String("goodluck").intern();
String newB =new String("goodluck").intern();
与: String newA = new String("goodluck");
StringnewB = newA;
功能是相同的。
1.5.String中作为参数传递过程理解
package javabase;
public class StringTest2 {
public void changeValue(String param){
// 传入方法后对值进行改变
param =param + "luck";
// 打印改变后的值
System.out.println("changeValue(Sring param) param = " + param);
}
public static void main(String[] args) {
StringTest2 test2 = new StringTest2();
String str = "good";
// 方法调用之前值
System.out.println(" main beformethod str = " + str);
test2.changeValue(str);
// 方法调用之后值
System.out.println(" main aftermethod str = " + str);
}
}
运行结果:
main befor methodstr = good
changeValue(Sring param) param = goodluck
main after method str = good
图解: