Java面试题之最扯淡的String

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循环

时间: 2024-10-05 19:41:22

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

扯淡过滤器之乱码篇

在JavaWeb开发中,Servlet过滤器可以很方便地帮助开发者做很多重复的事情,比如说这里要和大家分享的乱码问题.其实说起乱码自己也没有什么经验可谈,只是东拼西凑来出来的一些代码,这里说过滤器是一方面,另一方面还有其中用到的一些思想上的东西. 乱码产生的原因说来说去就一句话,编码和解码用的码表不同造成.但是要弄清楚这其中的原理,怕是自己也不清楚,只好扬长避短.Web开发中的乱码就发生在服务器和浏览器之间,这样根据乱码的作用者可以分为请求参数乱码和响应内容乱码,响应乱码容易解决,只要respo

工作随谈之扯淡

最近由于工作和个人原因没有怎么把收获的记录下来,消沉了快一天,脑子一片混沌,发现是该写写了不然脑子真的可能转不过了! IT是一个大染缸,也是一个比较定义比较广阔的行业,而我从事的工作只是里面的一样--软件测试! 最近因为我的顶头上司直接升为我们项目组的负责人,无疑这是一个大的调整,这也可能是我们整个项目面向互联网进军的脚步要开始加快.web.ipad.iphone各个项目都准备就绪,全线出击,这些项目压下来不知道怎么处理才好,作为一个合格的测试员需要保证上线以及上线后他们的正常,无疑老大给了我一

java笔试题(4)

abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? abstract的method 不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系! abstract的method 不可以是native的,native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用.例如,FileOutputSteam类要硬件打交道,底层的

java --面试题大全

        J2EE面试题   文档版本号:V2.0                   2016年11月 目 录 1. Java基础部分 8 1.1. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 8 1.2. Java有没有goto? 8 1.3. 说说&和&&的区别. 8 1.4. 在JAVA中如何跳出当前的多重嵌套循环? 8 1.5. switch语句能否作用在byte上,能否作用在long上,能否作用在String上?

java面试题大全

java面试笔试题大汇总     第一,谈谈final, finally, finalize的区别. 最常被问到. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统). 第四,&和&&的区别. 这个问得很少. 第五,HashMap和Hashtable的区

百度掉出BAT?扯淡前先知道啥是带路党(《越界》连载2)

你认识路当然不需要地图,但问题是在互联网上,就算你是骨灰级网民,也需要带路党.百度就是带路党 这两天,一篇题为百度掉出BAT序列的文章很火,火到我也不知道这玩意为啥那么吸引眼球.因为很标题党,很扯淡,正好我<越界--互联网+时代必先搞懂的大败局>连载到百度历史,不妨摘出来,让大家先看看百度怎么成为网民伟哥的吧. 文/张书乐 <越界--互联网+时代必先搞懂的大败局>连载之一 2010年3月,当时百度在中国最大的竞争对手谷歌以频受黑客攻击为由,关闭了谷歌中国的域名google.cn,并

Java面试题全集(中)

这部分主要是与Java Web和Web Service相关的面试题. 96.阐述Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行其service()方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet. 补充:Sun Microsystems公司在1996年发布Servlet技术就是为了和CGI进行竞争,Servlet是一个特殊的Java程

Java面试题下

这部分主要是开源Java EE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不讨论Struts 2的面试题,如果需要了解相关内容,可以参考我的另一篇文章<Java面试题集(86-115)>.此外,这篇文章还对企业应用架构.大型网站架构和应用服务器优化等内容进行了简单的探讨,这些内容相信对面试会很有帮助. 126.什么是ORM?答:对象关系映射(Object-Relational Mapping,简称OR

罗辑思维 140 认钱不认人(刚需是扯淡,一切都是稀缺,人生全是选择)——理性永远都是最珍贵的

18分左右: 1. 刚需是扯淡,包括生命(罗胖举了许多例子)(拒绝选择,拒绝选择带来的代价)2. 一切都是稀缺3. 人生全是选择要承担选择的后果 房价限制不了,市场是一个联通体系,捂住这个口,那就回那个口出来.毁掉房价:1.轰炸 2.限制租金 https://www.youtube.com/watch?v=Oxe757tCimA