一.相关概念java
二.8种基本类型的包装类和常量池缓存
Integer i1 = 40; Integer i2 = 40; System.out.println(i1==i2);//输出TRUE
这5种包装类默认建立了数值[-128,127]的相应类型的缓存数据,可是超出此范围仍然会去建立新的对象。分布式
//Integer 缓存代码 : public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } Integer i1 = 400; Integer i2 = 400; System.out.println(i1==i2);//输出false
Double i1=1.2; Double i2=1.2; System.out.println(i1==i2);//输出false
Integer i1 = 40; Integer i2 = new Integer(40); System.out.println(i1==i2);//输出false
Integer i1 = 40; Integer i2 = 40; Integer i3 = 0; Integer i4 = new Integer(40); Integer i5 = new Integer(40); Integer i6 = new Integer(0); System.out.println("i1=i2 " + (i1 == i2)); System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); System.out.println("i1=i4 " + (i1 == i4)); System.out.println("i4=i5 " + (i4 == i5)); System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); System.out.println("40=i5+i6 " + (40 == i5 + i6)); i1=i2 true i1=i2+i3 true i1=i4 false i4=i5 false i4=i5+i6 true 40=i5+i6 true
解释:语句i4 == i5 + i6,由于+这个操做符不适用于Integer对象,首先i5和i6进行自动拆箱操做,进行数值相加,即i4 == 40。而后Integer对象没法与数值进行直接比较,因此i4自动拆箱转为int值40,最终这条语句转为40 == 40进行数值比较。微服务
Java中的自动装箱与拆箱源码分析
三.String类和常量池性能
String str1 = "abcd"; String str2 = new String("abcd"); System.out.println(str1==str2);//false
这两种不一样的建立方法是有差异的,第一种方式是在常量池中拿对象,第二种方式是直接在堆内存空间建立一个新的对象。学习
只要使用new方法,便须要建立新的对象。优化
String str1 = "str"; String str2 = "ing"; String str3 = "str" + "ing"; String str4 = str1 + str2; System.out.println(str3 == str4);//false String str5 = "string"; System.out.println(str3 == str5);//true
java基础:字符串的拼接视频
public static final String A = "ab"; // 常量A public static final String B = "cd"; // 常量B public static void main(String[] args) { String s = A + B; // 将两个常量用+链接对s进行初始化 String t = "abcd"; if (s == t) { System.out.println("s等于t,它们是同一个对象"); } else { System.out.println("s不等于t,它们不是同一个对象"); } } s等于t,它们是同一个对象
A和B都是常量,值是固定的,所以s的值也是固定的,它在类被编译时就已经肯定了。也就是说:String s=A+B; 等同于:String s="ab"+"cd";对象
public static final String A; // 常量A public static final String B; // 常量B static { A = "ab"; B = "cd"; } public static void main(String[] args) { // 将两个常量用+链接对s进行初始化 String s = A + B; String t = "abcd"; if (s == t) { System.out.println("s等于t,它们是同一个对象"); } else { System.out.println("s不等于t,它们不是同一个对象"); } } s不等于t,它们不是同一个对象
A和B虽然被定义为常量,可是它们都没有立刻被赋值。在运算出s的值以前,他们什么时候被赋值,以及被赋予什么样的值,都是个变数。所以A和B在被赋值以前,性质相似于一个变量。那么s就不能在编译期被肯定,而只能在运行时被建立了。
public static void main(String[] args) { String s1 = new String("计算机"); String s2 = s1.intern(); String s3 = "计算机"; System.out.println("s1 == s2? " + (s1 == s2)); System.out.println("s3 == s2? " + (s3 == s2)); } s1 == s2? false s3 == s2? true
public class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.println((hello == "Hello") + " "); System.out.println((Other.hello == hello) + " "); System.out.println((other.Other.hello == hello) + " "); System.out.println((hello == ("Hel"+"lo")) + " "); System.out.println((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } } class Other { static String hello = "Hello"; } package other; public class Other { public static String hello = "Hello"; } true true true true false true``` 在同包同类下,引用自同一String对象. 在同包不一样类下,引用自同一String对象. 在不一样包不一样类下,依然引用自同一String对象. 在编译成.class时可以识别为同一字符串的,自动优化成常量,引用自同一String对象. 在运行时建立的字符串具备独立的内存地址,因此不引用自同一String对象.
若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:787707172,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。