public class TestString {
public static void main(String[] args) {
/** * **** String类型、包装类型、常量池(与堆、栈) * *
* 1)== :比较桟区地址
* 2)equals:String/Integer的 equals 比较(变量所指向的在常量池或堆区的)内容
*
* 3)String常量池
*
* 只要使用new定义,无论如何都返回新的引用(栈区保存新的地址),如果要创建的字符串在常量池没有找到,则要新加一个;另外在堆区开辟空间。
* 直接指定、或者使用纯字符串串联、或字符串加final常量来创建一个字符串,先检查常量池,如果在常量池没有找到,则在常量池添加一个并返回新的引用地址;如果找到,则返回相同的唯一的引用。
* 使用包含变量的表达式来创建字符串对象,则不仅会检查维护String池(没有则添加新的字符串),而且还会在堆区开辟空间、在栈区保存新的引用地址。
*
*
* 4)Byte,Short,Integer,Long,Character Boolean类型都实现了常量池(这类常量池范围: -128~127,)
* Double,Float两种浮点数类型的包装类则没有实现。
*
* 5)对于基本类型的变量和常量:变量和引用都存储在栈中,常量则存储在常量池中。 https://www.cnblogs.com/SaraMoring/p/5687466.html
*
* ------------------------------------------------------------------------------------
* https://zhidao.baidu.com/question/121174275.html
* java常量池不在堆中也不在栈中,是独立的内存空间管理。
* 1.栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
* 2.堆:存放所有new出来的对象。
* 3.常量池:存放字符串常量和基本类型常量(public static final)。
* 对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
*
*
*
*
*/
String str2 = "hello";
String str3 = "hello";
String str4 = new String("hello");
System.out.println(str2==str3); //true 使用常量池的 hello
System.out.println(str4==str3); //false 使用常量池的 hello,但是new则在返回新的引用
System.out.println(str4.equals(str3)); //true 比较指向的字符串常量池的内容
Integer i1=127;
Integer i2=127;
Integer i3=new Integer(127);
Integer i4=128;
Integer i5=128;
System.out.println(i1==i2); //true 使用常量池的127
System.out.println(i3==i2); //false 常量池也是只有一个127,但是new则在返回新的引用
System.out.println(i4==i5); //false 整数常量池只有 -128~127,超出范围返回新的引用
System.out.println(i2.equals(i3)); //true 比较指向堆区/常量池的内容
System.out.println(i4.equals(i5)); //true 比较指向堆区/常量池的内容
Boolean b1=false;
Boolean b2=false;
Boolean b3=new Boolean(false);
System.out.println(b1==b2); //true true\false在常量池
System.out.println(b3==b2); //false 使用了new则返回新的引用
System.out.println(b3.equals(b2)); //true 比较指向的在常量池的内容
//
String a = "ab";
String bb = "b";
String b = "a" + bb; //程序运行期来动态分配并将连接后的新地址赋给b
System.out.println((a == b)); //false
String a0 = "ab";
final String bb1 = "b"; //对于final修饰的变量,它在编译时被解析为常量值
String b0 = "a" + bb1;
System.out.println((a0 == b0)); //true
String a00 = "ab";
final String bb2 = getBB(); //程序运行期调用方法
String b00 = "a" + bb2; //动态分配地址为b
System.out.println((a00 == b00)); //false
}
private static String getBB() {
return "b";
}
}
原文地址:https://www.cnblogs.com/badboyh2o/p/9551725.html