博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java面试题之最扯淡的String
阅读量:6967 次
发布时间:2019-06-27

本文共 4827 字,大约阅读时间需要 16 分钟。

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 hello2: astore_13: ldc #3 // String hel5: astore_26: ldc #4 // String lo8: astore_3   //将操作数栈顶的值保存在本地变量表,变量地址放本地变量表3位置  9: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;12: aload_113: ldc #2 // String hello15: if_acmpne 2218: iconst_119: goto 2322: iconst_023: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V26: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;29: aload_130: new #7 // class java/lang/StringBuilder33: dup34: invokespecial #8 // Method java/lang/StringBuilder."
":()V37: ldc #3 // String hel    //这句加载常量到操作数栈 hel39: 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.tostring49: if_acmpne 5652: iconst_153: goto 5756: iconst_057: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V60: 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   //加载常量到操作数栈,常量是hello2: astore_13: ldc #3 // String hel5: astore_26: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;9: aload_110: ldc #2 // String hello12: if_acmpne 1915: iconst_116: goto 2019: iconst_020: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V23: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;26: aload_127: ldc #2 // String hello  加载常量29: if_acmpne 36    比较32: iconst_133: goto 3736: iconst_037: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V40: 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循环

posted on
2017-05-14 17:56 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/shuiyonglewodezzzzz/p/6853162.html

你可能感兴趣的文章
TSP问题
查看>>
ubuntu14.06 Lts开启ssh服务
查看>>
对象比较:Comparable 和 Comparator
查看>>
jsp中的contentType与pageEncoding的区别和作用
查看>>
java 调用启动远程shell脚本,启动spark
查看>>
Spring boot ----RestTemplate学习笔记
查看>>
[LUOGU] P3128 [USACO15DEC]最大流Max Flow
查看>>
windows2003server下能安装的MSN
查看>>
Caffe将自己的文件生成lmdb
查看>>
C# 枚举中的位运算
查看>>
Codeforces Global Round 1 晕阙记
查看>>
百度文化秘籍
查看>>
Algs4-1.3.33一个双向队列Deque-双向链表实现
查看>>
Algs4-2.2.29自然的归并排序(未解决)
查看>>
shell中数组基础语法
查看>>
P1215 母亲的牛奶
查看>>
回头再看第一次项目
查看>>
有无关键字new的区别
查看>>
Hashmap,Set,Map,List,ArrayList的区别
查看>>
3.Linux 文件的压缩与打包
查看>>