运行时常量池_各种数据类型的常量池技术

df98051c37377e5a0278ff860c1de4e0.png

一、前言

Java中常量池大体可以分为:静态常量池,运行时常量池。

class文件常量池:存在于class文件中,如经常使用的javap -verbose中;

运行时常量池:就是在class文件被加载进了内存之后,常量池保存在了方法区中。

通常说的常量池指的是运行时常量池,本文讨论的都是运行时常量池。

二、基本类型常量池

Java中基本类型的常量池技术不是由基本类型实现的,而是由基本类型对应的包装类型实现的。但是因为Java5.0后引入自动装包和自动拆包,所以这一点已经不重要了。

2c86301550805fef929deffeca0553be.png

2.1 Boolean常量池

代码1——常量池比较 true

package mypackage;
 
public class TestConstantPool {
	public static void main(String[] args) {
		Boolean boolean1 = true;
		Boolean boolean2 = true;
		System.out.println(boolean1 == boolean2);// 打印true 包装类型Boolean实现了常量池技术
		boolean1 = false;
		boolean2 = false;
		System.out.println(boolean1 == boolean2);// true
	}
}

输出:

true
true

代码2——新建对象比较 一定返回false

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Boolean boolean1 = new Boolean(true);
		Boolean boolean2 = new Boolean(true);
		System.out.println(boolean1 == boolean2);// false 不同对象指向不同地址
	}
 
}

输出:

false

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		boolean _b1=true;
		boolean _b2=true;
		System.out.println(_b1==_b2);//true
	}
 
}

输出:

true

金手指:Boolean/boolean

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,常量池(编译时类型为包装类型,运行时类型为基本类型)比较介于两者之间,常量池范围内(true|false)为true,又常量池覆盖Boolean所有范围(true|false),故Boolean常量池均为true。

2.2 字符型(Character)常量池

代码1——常量池比较(涉及常量池:Character在(0 ~ 127)使用常量池技术,返回为true,范围外在堆中新建对象,返回为false)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Character _cCharacter = (char) -1;
		Character _cCharacter2 = (char) -1;
		System.out.println(_cCharacter == _cCharacter2);// false
 
		Character _cCharacter3 = (char) 0;
		Character _cCharacter4 = (char) 0;
		System.out.println(_cCharacter3 == _cCharacter4);// true
 
		Character _cCharacter5 = (char) 127;
		Character _cCharacter6 = (char) 127;
		System.out.println(_cCharacter5 == _cCharacter6);// true
 
		Character _cCharacter7 = (char) 128;
		Character _cCharacter8 = (char) 128;
		System.out.println(_cCharacter7 == _cCharacter8);// false
	}
 
}

输出:

false
true
true
false

代码2——新建对象比较(直接比较new对象,一定为false,拆箱比较,一定为true)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Character _cCharacter0 = new Character((char) 0);
 
		Character _cCharacter = new Character((char) -1);
		Character _cCharacter2 = new Character((char) -1);
		System.out.println("新建对象后比较: " + (_cCharacter == _cCharacter2));
		System.out.println("自动拆箱后比较: " + (_cCharacter == _cCharacter2 + _cCharacter0));
 
		Character _cCharacter3 = new Character((char) 0);
		Character _cCharacter4 = new Character((char) 0);
		System.out.println("新建对象后比较: " + (_cCharacter3 == _cCharacter4));
		System.out.println("自动拆箱后比较: " + (_cCharacter3 == _cCharacter4 + _cCharacter0));
 
		Character _cCharacter5 = new Character((char) 127);
		Character _cCharacter6 = new Character((char) 127);
		System.out.println("新建对象后比较: " + (_cCharacter5 == _cCharacter6));
		System.out.println("自动拆箱后比较: " + (_cCharacter5 == _cCharacter6 + _cCharacter0));
 
		Character _cCharacter7 = new Character((char) 128);
		Character _cCharacter8 = new Character((char) 128);
		System.out.println("新建对象后比较: " + (_cCharacter7 == _cCharacter8));
		System.out.println("自动拆箱后比较: " + (_cCharacter7 == _cCharacter8 + _cCharacter0));
	}
 
}

输出:

新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		char _cCharacter = (char) -1;
		char _cCharacter2 = (char) -1;
		System.out.println(_cCharacter == _cCharacter2);// true
 
		char _cCharacter3 = (char) 0;
		char _cCharacter4 = (char) 0;
		System.out.println(_cCharacter3 == _cCharacter4);// true
 
		char _cCharacter5 = (char) 127;
		char _cCharacter6 = (char) 127;
		System.out.println(_cCharacter5 == _cCharacter6);// true
 
		char _cCharacter7 = (char) 128;
		char _cCharacter8 = (char) 128;
		System.out.println(_cCharacter7 == _cCharacter8);// true
	}
 
}

输出:

true
true
true
true

金手指:Character/char

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,常量池(编译时类型为包装类型,运行时类型为基本类型)比较介于两者之间,常量池范围内(0~127)为true,常量池范围外jvm会重新新建对象,故为false。

2.3 Byte常量池

代码1——常量池比较(-128~127全部为true,byte也不能超过这个范围,所以byte全部为true)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		// Byte _bByte=(byte) -129;
		// Byte _bByte2=(byte) -129; byte仅一个字节 -128~127 超出范围
 
		Byte _bByte3 = -128;
		Byte _bByte4 = -128;
		System.out.println(_bByte3 == _bByte4);
 
		Byte _bByte5 = 127;
		Byte _bByte6 = 127;
		System.out.println(_bByte5 == _bByte6);
 
		// Byte _bByte7=(byte) 128;
		// Byte _bByte8=(byte) 128; byte仅一个字节 -128~127 超出范围
	}
 
}

输出:

true
true

代码2——新建对象后比较(直接比较new对象,一定为false,拆箱比较,一定为true)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Byte _bByte0 = new Byte((byte) 0);
 
		Byte _bByte3 = new Byte((byte) -128);
		Byte _bByte4 = new Byte((byte) -128);
		System.out.println("新建对象后比较: " + (_bByte3 == _bByte4));
		System.out.println("自动拆箱后比较: " + (_bByte3 == _bByte4 + _bByte0));
 
		Byte _bByte5 = new Byte((byte) 127);
		Byte _bByte6 = new Byte((byte) 127);
		System.out.println("新建对象后比较: " + (_bByte5 == _bByte6));
		System.out.println("自动拆箱后比较: " + (_bByte5 == _bByte6 + _bByte0));
 
	}
 
}

输出:

新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
 
		byte _bByte3 = -128;
		byte _bByte4 = -128;
		System.out.println(_bByte3 == _bByte4);
 
		byte _bByte5 = 127;
		byte _bByte6 = 127;
		System.out.println(_bByte5 == _bByte6);
 
	}
 
}

输出:

true
true

金手指:Byte/byte

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,常量池(编译时类型为包装类型,运行时类型为基本类型)比较介于两者之间,常量池范围内(-128 ~ 127)为true,又常量池覆盖Byte所有范围(-128~127),故Byte常量池均为true。

2.4 Short常量池

代码1——常量池比较(涉及常量池:Short在(-128 ~ 127)使用常量池技术,返回为true,范围外在堆中新建对象,返回为false)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Short _sShort=-129;
		Short _sShort2=-129;
		System.out.println(_sShort==_sShort2);
		
		Short _sShort3=-128;
		Short _sShort4=-128;
		System.out.println(_sShort3==_sShort4);
		
		Short _sShort5=127;
		Short _sShort6=127;
		System.out.println(_sShort5==_sShort6);
		
		Short _sShort7=128;
		Short _sShort8=128;
		System.out.println(_sShort7==_sShort8);
	}
 
}

输出:

false
true
true
false

代码2——新建对象后比较(直接比较new对象,一定为false,与-128 ~ 127范围无关,纯对象比较;拆箱比较,一定为true,与-128 ~ 127范围无关,纯数值比较)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Short _sShort0 = new Short((short) 0);
 
		Short _sShort = new Short((short) -129);
		Short _sShort2 = new Short((short) -129);
		System.out.println("新建对象后比较: " + (_sShort == _sShort2));
		System.out.println("自动拆箱后比较: " + (_sShort == _sShort2 + _sShort0));
 
		Short _sShort3 = new Short((short) -128);
		Short _sShort4 = new Short((short) -128);
		System.out.println("新建对象后比较: " + (_sShort3 == _sShort4));
		System.out.println("自动拆箱后比较: " + (_sShort3 == _sShort4 + _sShort0));
 
		Short _sShort5 = new Short((short) 127);
		Short _sShort6 = new Short((short) 127);
		System.out.println("新建对象后比较: " + (_sShort5 == _sShort6));
		System.out.println("自动拆箱后比较: " + (_sShort5 == _sShort6 + _sShort0));
 
		Short _sShort7 = new Short((short) 128);
		Short _sShort8 = new Short((short) 128);
		System.out.println("新建对象后比较: " + (_sShort7 == _sShort8));
		System.out.println("自动拆箱后比较: " + (_sShort7 == _sShort8 + _sShort0));
	}
 
}

输出:

新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		short _sShort = -129;
		short _sShort2 = -129;
		System.out.println(_sShort == _sShort2);
 
		short _sShort3 = -128;
		short _sShort4 = -128;
		System.out.println(_sShort3 == _sShort4);
 
		short _sShort5 = 127;
		short _sShort6 = 127;
		System.out.println(_sShort5 == _sShort6);
 
		short _sShort7 = 128;
		short _sShort8 = 128;
		System.out.println(_sShort7 == _sShort8);
	}
 
}

输出:

true
true
true
true

金手指:Short/short

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,常量池(编译时类型为包装类型,运行时类型为基本类型)比较介于两者之间,常量池范围内(-128~127)为true,常量池范围外会jvm重新新建对象,故为false。

2.5 Integer常量池

代码1——常量池比较(涉及常量池:Integer在(-128 ~ 127)使用常量池技术,返回为true,范围外在堆中新建对象,返回为false)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Integer _iInteger=-129;
		Integer _iInteger2=-129;
		System.out.println(_iInteger==_iInteger2);
		
		Integer _iInteger3=-128;
		Integer _iInteger4=-128;
		System.out.println(_iInteger3==_iInteger4);
		
		Integer _iInteger5=127;
		Integer _iInteger6=127;
		System.out.println(_iInteger5==_iInteger6);
		
		Integer _iInteger7=128;
		Integer _iInteger8=128;
		System.out.println(_iInteger7==_iInteger8);
	}
 
}

输出:

false
true
true
false

代码2——新建对象比较(直接比较new对象,一定为false,与-128 ~ 127范围无关,纯对象比较;拆箱比较,一定为true,与-128 ~ 127范围无关,纯数值比较)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Integer _iInteger0=new Integer(0);
		
		Integer _iInteger=new Integer(-129);
		Integer _iInteger2=new Integer(-129);
		System.out.println("新建对象后比较: "+(_iInteger==_iInteger2));
		System.out.println("自动拆箱后比较: "+(_iInteger==_iInteger2+_iInteger0));
		
		Integer _iInteger3=new Integer(-128);
		Integer _iInteger4=new Integer(-128);
		System.out.println("新建对象后比较: "+(_iInteger3==_iInteger4));
		System.out.println("自动拆箱后比较: "+(_iInteger3==_iInteger4+_iInteger0));
		
		Integer _iInteger5=new Integer(127);
		Integer _iInteger6=new Integer(127);
		System.out.println("新建对象后比较: "+(_iInteger5==_iInteger6));
		System.out.println("自动拆箱后比较: "+(_iInteger5==_iInteger6+_iInteger0));
		
		Integer _iInteger7=new Integer(128);
		Integer _iInteger8=new Integer(128);
		System.out.println("新建对象后比较: "+(_iInteger7==_iInteger8));
		System.out.println("自动拆箱后比较: "+(_iInteger7==_iInteger8+_iInteger0));
	}
 
}

输出:

新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		int _int1 = -129;
		int _int2 = -129;
		System.out.println(_int1 == _int2);
 
		int _int3 = -128;
		int _int4 = -128;
		System.out.println(_int3 == _int4);
 
		int _int5 = 127;
		int _int6 = 127;
		System.out.println(_int5 == _int6);
 
		int _int7 = 128;
		int _int8 = 128;
		System.out.println(_int7 == _int8);
	}
 
}

输出:

true
true
true
true

金手指:Integer/int

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,常量池(编译时类型为包装类型,运行时类型为基本类型)比较介于两者之间,常量池范围内(-128~127)为true,常量池范围外会jvm重新新建对象,故为false。

2.6 Long常量池

代码1——常量池比较(涉及常量池:Long在(-128 ~ 127)使用常量池技术,返回为true,范围外在堆中新建对象,返回为false)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Long _iLong = (long) -129;
		Long _iLong2 = (long) -129;
		System.out.println(_iLong == _iLong2);
 
		Long _iLong3 = (long) -128;
		Long _iLong4 = (long) -128;
		System.out.println(_iLong3 == _iLong4);
 
		Long _iLong5 = (long) 127;
		Long _iLong6 = (long) 127;
		System.out.println(_iLong5 == _iLong6);
 
		Long _iLong7 = (long) 128;
		Long _iLong8 = (long) 128;
		System.out.println(_iLong7 == _iLong8);
	}
 
}

输出:

false
true
true
false

代码2——新建对象比较(直接比较new对象,一定为false,与-128 ~ 127范围无关,纯对象比较;拆箱比较,一定为true,与-128 ~ 127范围无关,纯数值比较)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Long _iLong0 = new Long(0);
 
		Long _iLong = new Long((long) -129);
		Long _iLong2 = new Long((long) -129);
		System.out.println("新建对象后比较: " + (_iLong == _iLong2));
		System.out.println("自动拆箱后比较: " + (_iLong == _iLong2 + _iLong0));
 
		Long _iLong3 = new Long((long) -128);
		Long _iLong4 = new Long((long) -128);
		System.out.println("新建对象后比较: " + (_iLong3 == _iLong4));
		System.out.println("自动拆箱后比较: " + (_iLong3 == _iLong4 + _iLong0));
 
		Long _iLong5 = new Long((long) 127);
		Long _iLong6 = new Long((long) 127);
		System.out.println("新建对象后比较: " + (_iLong5 == _iLong6));
		System.out.println("自动拆箱后比较: " + (_iLong5 == _iLong6 + _iLong0));
 
		Long _iLong7 = new Long((long) 128);
		Long _iLong8 = new Long((long) 128);
		System.out.println("新建对象后比较: " + (_iLong7 == _iLong8));
		System.out.println("自动拆箱后比较: " + (_iLong7 == _iLong8 + _iLong0));
	}
 
}

输出:

新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true
新建对象后比较: false
自动拆箱后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		long _iLong = -129L;
		long _iLong2 = -129L;
		System.out.println(_iLong == _iLong2);
 
		long _iLong3 = -128L;
		long _iLong4 = -128L;
		System.out.println(_iLong3 == _iLong4);
 
		long _iLong5 = 127L;
		long _iLong6 = 127L;
		System.out.println(_iLong5 == _iLong6);
 
		long _iLong7 = 128L;
		long _iLong8 = 128L;
		System.out.println(_iLong7 == _iLong8);
	}
 
}

输出:

true
true
true
true

金手指:Long/long

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,常量池(编译时类型为包装类型,运行时类型为基本类型)比较介于两者之间,常量池范围内(-128~127)为true,常量池范围外会jvm重新新建对象,故为false。

2.7 Float常量池

代码1——常量池比较(涉及常量池:Float无常量池技术,所以在堆中新建对象,所以返回为false)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		Float _fFloat = 1.0f;
		Float _fFloat2 = 1.0f;
		System.out.println(_fFloat == _fFloat2);// false 浮点型没有实现常量池技术
	}
 
}

输出:

false

代码2——新建对象比较(直接比较new对象,一定为false,与-128 ~ 127范围无关,纯对象比较;拆箱比较,一定为true,与-128 ~ 127范围无关,纯数值比较;整个过程与常量池技术无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Float _fFloat0 = new Float(0.0f);
 
		Float _fFloat = new Float(1.0f);
		Float _fFloat2 = new Float(1.0f);
		System.out.println("新建对象后比较: " + (_fFloat == _fFloat2));
		System.out.println("自动拆箱后比较: " + (_fFloat == _fFloat2 + _fFloat0));
 
	}
 
}

输出:

新建对象后比较: false
新建对象后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		float _float1 = 1.0f;
		float _float2 = 1.0f;
		System.out.println(_float1 == _float2);
 
	}
 
}

输出:

true

金手指:Float/float

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,Float无常量池技术,常量池比较jvm会重新新建对象,故为false。

2.8 Double常量池

代码1——常量池比较(涉及常量池:Double无常量池技术,所以在堆中新建对象,所以返回为false)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		Double _dDouble = 1.0d;
		Double _dDouble2 = 1.0d;
		System.out.println(_dDouble == _dDouble2);// false 浮点型没有实现常量池技术
	}
 
}

输出:

false

代码2——新建变量比较(直接比较new对象,一定为false,与-128 ~ 127范围无关,纯对象比较;拆箱比较,一定为true,与-128 ~ 127范围无关,纯数值比较;整个过程与常量池技术无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		Double _dDouble0 = new Double(0.0d);
 
		Double _dDouble = new Double(1.0d);
		Double _dDouble2 = new Double(1.0d);
		System.out.println("新建对象后比较: " + (_dDouble == _dDouble2));// false 浮点型没有实现常量池技术															
		System.out.println("自动拆箱后比较: " + (_dDouble == _dDouble2 + _dDouble0));
	}
 
}

输出:

新建对象后比较: false
自动拆箱后比较: true

注意: 当出现运算符的时候,包装类型不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较,所以变成了两个基本类型之间的比较,仅比较值,则为true。

代码3——基本类型比较(true 栈内存中,数值相等即为true,与常量池无关)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
 
		double _dDouble = 1.0d;
		double _dDouble2 = 1.0d;
		System.out.println(_dDouble == _dDouble2);
 
	}
 
}

输出:

true

金手指:Double/double

第一,基本类型仅比较值,全为true;

第二,新建对象比较引用(即内存地址),全为false, 运算符拆箱后变为基本类型,全为true;

第三,Double无常量池技术,常量池比较jvm会重新新建对象,故为false。

三、引用类型常量池(String常量池)

package mypackage;
 
public class TestConstantPool {
 
	public static void main(String[] args) {
		String s1 = "Hello";
		String s2 = "Hello";
		String s3 = "Hel" + "lo";
		String s4 = "Hel" + new String("lo");
		String s5 = new String("Hello");
		String s6 = s5.intern();   
		String s7 = "H";
		String s8 = "ello";
		String s9 = s7 + s8;   // 
		          
		System.out.println(s1 == s2);  // true   理由:s1和s2右边赋值都是显式写死的,是编译器可以预知的,编译期间,直接放到class文件的常量池中,运行时,指向同一个地址
		System.out.println(s1 == s3);  // true   理由:s1右边是显式写死的,s3也是显式写死的,没有使用变量,所有s1、s3都是编译器可以预见的,编译时放入静态常量池中,指向同一地址
		System.out.println(s1 == s4);  // false  理由:s4右边拼接的时候使用了new String(),编译时不可预知,需要运行时确定,
		System.out.println(s1 == s9);  // false  理由:s9由s7、s8拼接,s7和s8都是变量,编译时不可预知
		System.out.println(s4 == s5);  // false  理由:s4右边使用new String(),编译时不可预知,s5右边也使用new String(),编译时不可预知
		System.out.println(s1 == s6);  // true   理由:s5已经在堆中,s6 = s5.intern();
		//intern方法会尝试将Hello字符串添加到常量池中,并返回其在常量池中的地址,因为常量池中已经有了Hello字符串,所以intern方法直接返回地址;而s1在编译期就已经指向常量池了,因此s1和s6指向同一地址,相等。
	}
 
}

输出:

true    // 两边都有变量,但是没有变量拼接
true   // 两边变量,右边常量拼接
false   // 两边变量,右边变量拼接,有newString() 一定false
false   // 两边都有变量,右边变量拼接,为false,没有intern()和final
false   // 两边都有变量,右边变量拼接,有newString() 一定false
true   两边都有变量,右边变量拼接,但是右边intern()

四、面试金手指

4.1 对象类型

对于八种对象(即boolean character byte short int long float double):

第一,如果直接比较new对象,一定为false,与-128 ~ 127范围无关,纯对象比较;

第二,对于拆箱:short int long float double (即后面五种)拆箱比较,一定为true,与-128 ~ 127范围无关,纯数值比较(拆箱比较等同于下面的基本数据类型比较,全为true),整个过程与常量池技术无关。

4.2 基本类型

对于基本类型(boolean char byte short int long float double)都栈内存上,不涉及-128 ~ 127的数值范围,与常量池技术无关。

4.3 常量池技术

对于六种类型使用的常量池技术:

boolean 全部为true 取值就两个;

Character 0-127 全部为true 超出为false;

byte -128~127 为true,但是它的取值范围就是这样,所有全部为true;

Short Integer Long -128 ~ 127 全部为true,其他为false;

Float Double 全部为false,没有常量池技术,都要在堆上新建。

五、尾声

各种数据类型的常量池技术,完成了。

天天打码,天天进步!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值