String是个对象,默认值为null,但是又是一个特殊的对象。
例如赋予一个字符串"a",或new String(),
编译时常量:String a = "welcome";
运行时常量:String b = new String("welcome");
例如赋予一个字符串"a",或new String(),
编译时常量:String a = "welcome";
运行时常量:String b = new String("welcome");
分析:
(1)编译时就可以确定时常量“welcome”存放与方法区常量池。
(2)new 一定是运行从堆中申请空间存放数据。同时返回推中起始地址给b引用。
常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。
Java会确保一个字符串常量只有一个拷贝。
那么我们看这个比较:
String a1 = "a"; String a2 = "a";
system.out.println(a1 == a2);
打印结果为true。
因为编译器就可以确定他们存放在常量池中,而且数据仅有一份。
new 关键字代表从堆中申请空间。变量b中存放一个常量。下面怎么解析那?
system.out.println(a == b.intern())// true
我们知道运行时常量池(Runtime Constant Pool):方法区的一部分,所有线程共享。虚拟机加载Class后把常量池中的数据放入到运行时常量池。
一旦b.intern。这个操作时这样执行的:运行时常量池可以扩充,这个前提下,jvm会去常量池中查找常量池中是否有unicodeb编码相同的常量,若有返回地址,没有则加入新常量,并且返回地址。