1. 不可变String
public class String相关 {
static String getA(){return "a";}
public static void main(String[] args) {
String a = "a";
String c = "ab";
final String f = "a";
String b = a+"b";//a为局部变量,编译器不会对其进行优化,为合并成新的字符串
String d = new String(b);//创建等值字符串,即等值char[],但是会开辟新的内存空间
String e = getA()+"b";//
String g = f + "b";//编译期可以确定f的内容,为final修饰,编译器优化
System.out.println(b==c);
System.out.println(d==c);
System.out.println(e==c);
System.out.println(g==c);
System.out.println("..................");
System.out.println(b.intern()==c.intern());
System.out.println(d.intern()==c.intern());
System.out.println(e.intern()==c.intern());
}
}
输出结果为:
false
false
false
true
..................
true
true
true
JVM编译器优化:当编译器在编译代码:String a = "a" + "b" +1这类代码时,会将其编译"ab1”,因为三个都是固定值,无需再进行任何计算,所以会这样进行优化,同样变量声明为final的时候也会进行优化,但是如果出现变量则不会对其进行优化,比如定义的变量a,具有返回值的方法等等~ intern()调用之后,JVM会在常量池中通过equal方法查找是否有等值的String,有就返回常量池中这个String的地址,故上面字符串最终内容一致就会返回true。
StringBuidler.append()与String + 的执行效率:
如果拼接对象是常量,则在编译器编译时进行合并优化,这个操作是编译阶段完成,不需要再单独的分配内存,肯定是String的 + 操作快,若含有变量,则其发生过程如下:
String a = "a";
String b = "b";
String c = a + b + "c";
实际上编译器编译时为
String a = "a";
String b = "b";
StringBuilder tmp = new StringBuilder();
tmp.append(a).append(b).append("f");
String c = tmp.toString();
更多内容见链接
2. 装箱和拆箱
package 面试易错题目;
public class 装箱和拆箱 {
public static void main(String[] args) {
Integer a = 1; //出发自动装箱
Integer b = new Integer(2); //不会触发
Integer c = 3;
Integer d = 3;
//Integer已经默认创建了数值【-128-127】的Integer缓存数据
//也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查找有没有该值的对象,
//如果有直接返回该对象的引用;如果没有,则使用New keyword创建一个对象,并返回该对象的引用地址
Integer e = 321; //超过127,新建对象
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println("1: "+(c==d));
System.out.println("2: "+ (e==f));
//当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,
//而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。
System.out.println("3: "+(c==(a+b))); //因此它们比较的是数值是否相等
System.out.println("4: "+(c.equals(a+b)));
System.out.println("5: "+ (g==(a+b)));
System.out.println("6: "+ (g.equals(a+b))); //对于包装器类型,equals方法并不会进行类型转换
//对于a+h,先自动触发拆箱,就变成了int类型和long类型相加,
//这个会触发类型晋升,结果是long类型的,然后会触发装箱过程,就变成Long了
System.out.println("7: "+ (g.equals(a+h)));
Double d1=100.0;
Double d2=100.0;
System.out.println("..........");
//Double每次都会new一个对象出来,故为false
System.out.println(d1==d2);
}
}
输出:
1: true
2: false
3: true
4: true
5: true
6: false
7: true
..........
false
更多内容点击链接
未完待续...