Java中字符串比较的一道面试题

题目:

public class Test {

    public static void main(String[] args) {
        String a = "hello";  
        String b = "hello";
        String c = a + b;
        String d = a + "hello";
        String e = a + b;

        System.out.println(a == b);   
        System.out.println(a == c);
        System.out.println(c == d); 
        System.out.println(c == e); 
    }

}

输出结果:

true
false
false
false

解析:直接把上面代码进行反编译一下就知道其中的原理了。

这里写图片描述

从上面可以看到字符的的加操作其实是创建了一个StringBuilder对象,第一个字符串作为初始化参数传入StringBuilder对象,第二个参数使用StringBuilder的append操作添加到StringBuilder,这样就完成了加操作,所以新得到的对象是创建出来的一个新的StringBuilder对象,它存放在堆中,所以从上面看到c和e是不同的原因就是它们是新创建出来的两个不同的对象。a跟b相同的原因就是因为字面量字符串”hello”存放在常量区,它们两个都指向的是同一个字符串。

上面可以进行如下理解:

String a = "hello";  
String b = "hello";

String tmp = String.valueOf(a);
StringBuilder sb = new StringBuilder(tmp);
sb.append(b);
String c = sb.toString();

String tmp = String.valueOf(a);
StringBuilder sb = new StringBuilder(tmp);
sb.append("hello");
String d = sb.toString();

String tmp = String.valueOf(a);
StringBuilder sb = new StringBuilder(tmp);
sb.append(b);
String e = sb.toString();

补充:
类的final变量和普通变量有什么区别?

public class Test {
    public static void main(String[] args)  {
        String a = "hello2"; 
        final String b = "hello";
        String d = "hello";
        String c = b + 2; 
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));
    }
}

结果:

true
false

这里面就是final变量和普通变量的区别了,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。这种和C语言中的宏替换有点像。因此在上面的一段代码中,由于变量b被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b 替换为它的值。而对于变量d的访问却需要在运行时通过链接来进行。

下面反编译一下看一下就知道确实编译器做了手脚。

这里写图片描述

不过要注意,只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,比如下面的这段代码就不会进行优化:

public class Test {
    public static void main(String[] args)  {
        String a = "hello2"; 
        final String b = getHello();
        String c = b + 2; 
        System.out.println((a == c));

    }

    public static String getHello() {
        return "hello";
    }
}

这段代码的输出结果为false。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值