SB里面的toString方法如下,为什么需要这个,查看JVM虚拟机指令用,+号会变成new SB()的,然后调用toString方法
  public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}

  

public class ThreadException
{ public static void main(String[] args)
{
        没加final的代码
String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo");
System.out.println(hello == "hel" + lo); }
}
没加final的代码反编译回来后的代码
import java.io.PrintStream;

public class ThreadException
{
public static void main(String[] paramArrayOfString)
{
String str1 = "hello";
String str2 = "hel";
String str3 = "lo";
System.out.println(str1 == "hello");
System.out.println(str1 == "hel" + str3);
}
}
没加final的虚拟机执行的指令集如下
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String hello
2: astore_1
3: ldc #3 // String hel
5: astore_2
6: ldc #4 // String lo
8: astore_3 //将操作数栈顶的值保存在本地变量表,变量地址放本地变量表3位置
9: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
12: aload_1
13: ldc #2 // String hello
15: if_acmpne 22
18: iconst_1
19: goto 23
22: iconst_0
23: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V
26: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_1
30: new #7 // class java/lang/StringBuilder
33: dup
34: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V
37: ldc #3 // String hel    //这句加载常量到操作数栈 hel
39: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
42: aload_3          //加载一个本地变量到操作数栈,从本地变量表3这个位置,将里面的值放到操作数栈上去
43: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
46: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;//SB.tostring
49: if_acmpne 56
52: iconst_1
53: goto 57
56: iconst_0
57: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V
60: return

  再看下面这个,多加了一个final

加了final的代码
public class ThreadException
{ public static void main(String[] args)
{
String hello = "hello";
String hel = "hel";
final String lo = "lo";
System.out.println(hello == "hel" + "lo");//true
System.out.println(hello == "hel" + lo);//true
}
}
加了final后反编译回来的代码
import java.io.PrintStream; public class ThreadException
{
public static void main(String[] paramArrayOfString)
{
String str4 = "hello";
String str5 = "hel";
System.out.println(str4 == "hello");
System.out.println(str4 == "hello");
}
}
看下加了final的虚拟机代码
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String hello //加载常量到操作数栈,常量是hello
2: astore_1
3: ldc #3 // String hel
5: astore_2
6: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: ldc #2 // String hello
12: if_acmpne 19
15: iconst_1
16: goto 20
19: iconst_0
20: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V
23: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_1
27: ldc #2 // String hello 加载常量
29: if_acmpne 36    比较
32: iconst_1
33: goto 37
36: iconst_0
37: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V
40: return
}

  再来看这段代码

public class ThreadException
{

  加了final
public static void main(String[] args)
{ String s = new String("abc");
final String s1 = "abc";
String s2 = new String("abc");
final String s3 = "abc";
System.out.println(s == s.intern());
System.out.println(s1 == s2.intern());
System.out.println(s2.intern() == s2.intern());
System.out.println(s3 == s1);
}
}
加了final反编译回来的代码

import java.io.PrintStream;

public class ThreadException
{
public static void main(String[] paramArrayOfString)
{
String str1 = new String("abc"); String str2 = new String("abc"); System.out.println(str1 == str1.intern());
System.out.println("abc" == str2.intern());
System.out.println(str2.intern() == str2.intern());
//这段是不是很惊讶
System.out.println(true);
}
}
是不是很扯淡?

  再看没加final的

public class ThreadException
{ public static void main(String[] args)
{
  没加final的代码
String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");
String s3 = "abc";
System.out.println(s == s.intern());
System.out.println(s1 == s2.intern());
System.out.println(s2.intern() == s2.intern());
System.out.println(s3 == s1);
}
}
没加final反编译后的代码

import java.io.PrintStream;

public class ThreadException
{
public static void main(String[] paramArrayOfString)
{
String str1 = new String("abc");
String str2 = "abc";
String str3 = new String("abc");
String str4 = "abc";
System.out.println(str1 == str1.intern());
System.out.println(str2 == str3.intern());
System.out.println(str3.intern() == str3.intern());
System.out.println(str4 == str2);
}
}

  是不是都感觉很扯淡,还是C++ Primer里面那句话,对于字面量字符串的处理,有些编译器会保存一个,有些会保存多个副本,所以,

想判断String字面量是否相等,老老实实的for循环

Java面试题之最扯淡的String的更多相关文章

  1. 如何修改int的打印内容——史上最难的JAVA面试题

    序 今天看到了一个比较特别的面试题,考察的是如何改变int的System.out.print的结果.题目如下: 下面的一句话"这是初级java实习生面试题"非常挑衅的激起了大家做题 ...

  2. java 面试题整理(不定期更新)

    一.Java基础 1.Java面向对象的三个特征与含义 三大特征是:封装.继承和多态. 封装是指将某事物的属性和行为包装到对象中,这个对象只对外公布需要公开的属性和行为,而这个公布也是可以有选择性的公 ...

  3. java 考试试题

    Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法,其他.有些题来自网上搜集整理,有些题来自学员 ...

  4. Java面试题合集(一)

    接下来几篇文章准备系统整理一下有关Java的面试题,分为基础篇,javaweb篇,框架篇,数据库篇,多线程篇,并发篇,算法篇等等,陆续更新中. 其他方面如前端后端等等的面试题也在整理中,都会有的. 所 ...

  5. Java面试题之基础篇概览

    Java面试题之基础篇概览 1.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,且public的类名必须与文件名相一致. 2.Ja ...

  6. dba和运维专家们说有丰富的大型分布式系统架构设计经验纯属扯淡

    如果,一开始就从事dba和运维的专家们说他们有丰富的大型分布式系统架构设计经验,那纯属扯淡.除非,他们从是从开发专家或者架构师转型而来,那么他们才有资格说自己有丰富的大型分布式系统架构设计经验. 运维 ...

  7. java面试题0004-在一个类上是否可以用abstract和final同时加以修饰?

    我们先用提干两个修饰词中的任意一个创建一个类 package components.javaTest.day4_20200910; /** * Question004: * java面试题0004-在 ...

  8. 震撼,java面试题整合(良心制作)11万多字拿去。持续更新【可以收藏】

    一.javaSE面试题整合 Java部分 JDK中哪些类是不能继承的?[信雅达面试题] [参考答案] 不能继承的是类是那些用final关键字修饰的类.一般比较基本的类型或防止扩展类无意间破坏原来方法的 ...

  9. html5吹牛扯淡篇,闲话内容。

    09年提出对媒体查询的草案,到今天的广泛运用,w3c带我们走进了个性化定制的殿堂.这些之所以会被认可会被写进世界级标准,因为他越来越适应广大用户的需求,需求就像一条锁链带动或者牵引整个互联网开发工作. ...

随机推荐

  1. 在linux下使用百度ueditor编辑器上传图片

    百度ueditor编辑器虽然强大,但是也有不足的地方.如果对ueditor流程不是很熟悉可以说走的弯路比较多,费力不讨好.下面呢,就是要解决ueditor遇到的问题. 用ueditor上传图片遇到的问 ...

  2. 消息映射(C++)(转)

    摘要:控件通知消息有很多种,但是有一种是很常用,但是又不是很容易掌握的,那就是WM_NOTIFY,我试着对此做一下比较全面的论述,有不对的地方,还希望各路大虾批评指正.     控件通知消息     ...

  3. response.getWriter().write()与out.print()的区别(转)

    1.首先介绍write()和print()方法的区别:  (1).write():仅支持输出字符类型数据,字符.字符数组.字符串等  (2).print():可以将各种类型(包括Object)的数据通 ...

  4. Verilog读写文件

    在通过编写Verilog代码实现ram功能时,需要自己先计算寄存器的位数和深度再编写代码. 而如果需要在编写的ram中预置值的话,就需要使用Verilog语言编写程序读写文件,来将相应的数据赋给寄存器 ...

  5. 快速找到Office应用程序安装路径

    p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...

  6. UNION ALL合表查询

    有时候需要连表查询数据,可以使用union all来做合表. 语法: SELECT column_name FROM table1UNION ALLSELECT column_name FROM ta ...

  7. 浩哥解析MyBatis源码(六)——DataSource数据源模块之池型数据源

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6675674.html 1 回顾 上一文中解读了MyBatis中非池型数据源的源码,非池型也 ...

  8. jmeter、java自动化学习地址

    自动化学习社区地址:http://www.hordehome.com/c/14-category jmeter学习地址(范丰平博客):http://www.cnblogs.com/fengpingfa ...

  9. chrome浏览器tab页内存占用变大,网站变慢为哪般?

    问题概述: 公司做的是BS应用. 之前我们的后台服务器程序是带状态的,用ehcache存储登录状态:这两天被我改成了redis存储,应用本身不再存储登录状态. 然后自测,我在测试某个很耗时间的网页操作 ...

  10. 跟着刚哥梳理java知识点——基本数据类型(三)

    1.8种基本数据类型 1)4种整数类型(byte.short.int.long) [知识点] 类型 存储空间 数值范围 byte 1字节=8位 -128-127 short 2字节 -2的15次方-2 ...