第一期:Java面试 - 100题,梳理各大网站优秀面试题。大家可以跟着我一起来刷刷Java理论知识

[005] - JavaSE面试题(五):String类

第1问:String、StringBuffer、StringBuilder 的区别?

  • 都是final类,都不允许被继承
  • String长度是不可变的,StringBuffer和StringBuilder长度是可变的。
  • StringBuffer是线程安全的,StringBuilder是线程不安全的,但他们两个中的所有方法都是相同的,StringBuffer在StringBuilder的方法之上加了synchronized修饰,保证线程安全。
  • StringBuilder比StringBuffer拥有更好的性能。
  • 如果一个String类型的字符串,在编译时就可以确定是一个字符串常量,则编译完成之后,字符串会自动拼接成一个常量。此时String的速度比StringBuilder和StringBuffer的性能更好。

第2问:String str="aaa" 与 String str=new String("aaa")一样吗?

  • 不同,内存分配的方式不同。
  • String str="aaa",创建了1个对象,创建的"aaa"是常量,jvm将其分配在常量池中;
  • String str=new String("aaa"),创建了2个对象,一个是在常量池中,一个在堆内存中。

第3问:String str="aa" ,String s="bb" ,String aa=aa+s; 一共创建了几个对象?

  • 一共有2个引用,3个对象;
  • "aa"与"bb"都是常量,常量的值不能改变,当执行字符串拼接的时候,会创建一个新的常量"aabb",将其存到常量池中。

第4问:String s = "Hello"; s = s + " world!"; 这两行代码执行后,原始的 String 对象中的内容到底变了没有?

没有。

因为 String 被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s 原先指向一个 String 对象,内容是 "Hello",然后我们对 s 进行了“+”操作,那么 s 所指向的那个对象是没有发生变化的。这时,s 不指向原来那个对象了,而指向了另一个 String 对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。

结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用 String 来代表字符串的话会引起很大的内存开销。因为 String 对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个 String 对象来表示。这时,应该考虑使用 StringBuffer 类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。同时,如果要使用内容相同的字符串,不必每次都 new 一个 String。例如要在构造器中对一个名叫 s 的 String 引用变量进行初始化,把它设置为初始值,应当这样做:

public class Demo {
private String s;
...
s = "Initial Value";
...
}

而非s = new String("Initial Value");

后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为 String 对象不可改变,所以对于内容相同的字符串,只要一个 String 对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的 String 类型属性 s 都指向同一个对象。

上面的结论还基于这样一个事实:

  • 对于字符串常量,如果内容相同,Java 认为它们代表同一个 String 对象。
  • 而用关键字 new 调用构造器,总是会创建一个新的对象,无论内容是否相同。
  • 至于为什么要把 String 类设计成不可变类,是它的用途决定的。其实不只 String,很多 Java 标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。
  • 不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。
  • 当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以 Java 标准类库还提供了一个可变版本,即 StringBuffer。

第5问:判断下面代码的执行结果

String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true

原因:s1记录的是堆内存中对象的地址,s2记录的是常量池中的地址

String s1 = "a" + "b" + "c";
String s2 = "abc";
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true

原因:java中有常量优化机制,编译时就把 "a" + "b" + "c"变成“abc”赋值给s1

String s1 = "ab";
String s2 = "abc";
String s3 = s1 + "c";
System.out.println(s3 == s2); //false
System.out.println(s3.equals(s2)); //true

原因:因为s1是一个变量,jvm运行的时候不认为s3="abc",也就是无法使用常量池。因此s3会重新创建一个对象。

[005] - JavaSE面试题(五):String类的更多相关文章

  1. JAVA基础复习与总结<五> String类_File类_Date类

    String类 .Java字符串就是Unicode字符序列,例如串“Java”就是4个Unicoe字符组成. .Java没有内置的字符串类型,而是在标准java类库中提供了一个预定义的类String, ...

  2. 面试题:String类通用构造,拷贝构造,析构,赋值函数实现

    已知 String 类定义如下: class String { public: //通用构造函数 String(const char* str = NULL); //拷贝构造函数 String(con ...

  3. 【面试题】String类、包装类的不可变性

    不可变类的意思是创建该类的实例后,该实例的实例变量是不可改变的.Java提供的8个包装类和String类都是不可变类.因此String和8个包装类都具有不可变性. 就拿String类来说,通过阅读St ...

  4. String类中的常用方法

    String类 一.转换成String方法 1.public String(); 空参构造 初始化一个新创建的 String 对象,使其表示一个空字符序列 2.public String(byte[] ...

  5. JavaSE 面试题: 类初始化和实例初始化等

    JavaSE 面试题 类初始化和实例初始化等 class Father { private int i = test(); private static int j = method(); stati ...

  6. Java入门篇(五)——Java的字符串/String类

    前面在举例时有出现过String的例子,当时肯定有一部分朋友不知道这个是做什么用的.其实String类是Java中一个比较特殊的类,字符串即String类,它不是Java的基本数据类型之一,但可以像基 ...

  7. Java入门篇(五)——字符串/String类

    前面在举例时有出现过String的例子,当时肯定有一部分朋友不知道这个是做什么用的.其实String类是Java中一个比较特殊的类,字符串即String类,它不是Java的基本数据类型之一,但可以像基 ...

  8. 第五周学习总结&第三次实验报告(String类的应用)

    第五周学习总结 1.学习了继承的相关知识点: (1) 继承的格式为class 子类 extends 父类{} (2) 继承实际上是通过子类去扩展父类的功能 (3) 一个子类只能继承一个父类,也就是说, ...

  9. JavaSE学习笔记(5)---内部类和String类

    JavaSE学习笔记(5)---内部类和String类 一.内部类基础 转自菜鸟教程 ​ 在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来 ...

随机推荐

  1. 网络模型mAP计算实现代码

    网络模型mAP计算实现代码 一.mAP精度计算 这里首先介绍几个常见的模型评价术语,现在假设我们的分类目标只有两类,计为正例(positive)和负例(negtive)分别是: 1)True posi ...

  2. CUDA 7 Stream流简化并发性

    CUDA 7 Stream流简化并发性 异构计算是指高效地使用系统中的所有处理器,包括 CPU 和 GPU .为此,应用程序必须在多个处理器上并发执行函数. CUDA 应用程序通过在 streams  ...

  3. 【.NET 与树莓派】温度/湿度传感器——SHT30

    SHT3XX 系列的传感,常见的有三种:SHT 30.SHT 31.SHT 35.其中,比较便宜性价比较愉快的是 SHT 30. DHT 11 模块也是检测温度.湿度的,但SHT 11 使用的不是我们 ...

  4. 如何安装/导入Arduino库文件及库文件的不同位置与区别(以eFLL中嵌入式模糊逻辑库为例)

    网上有数百个可在Aruduino中使用的库,这些代码集使得我们无需从0-1地搭建我们所需功能,这使得学习和使用Arduino变得更加方便简单.除此之外,平时直接从网上download下的代码也很有可能 ...

  5. 【Azure 应用服务】Azure Web App的服务(基于Windows 操作系统部署)在被安全漏洞扫描时发现了TCP timestamps漏洞

    问题背景 什么是TCP timestamps(TCP 时间戳)? The remote host implements TCP Timestamps, as defined by RFC1323 (h ...

  6. 数据结构与算法Python版 熟悉哈希表,了解Python字典底层实现

    Hash Table 散列表(hash table)也被称为哈希表,它是一种根据键(key)来存储值(value)的特殊线性结构. 常用于迅速的无序单点查找,其查找速度可达到常数级别的O(1). 散列 ...

  7. 『言善信』Fiddler工具 — 13、Fiddler断点功能的使用详解

    目录 1.Fiddler断点的应用 2.断点的分类 3.设置全局断点 (1)设置before Requests全局断点: (2)设置After Responses全局断点: 4.设置局部断点 (1)设 ...

  8. Django基础之auth模块

    内容概要 用户认证模块auth auth模块补充 auth_user表扩展字段 内容详细 auth模块 主要是用来做用户相关的功能 注册 登录 验证 修改密码 注销 ​ 访问admin需要管理员账号 ...

  9. 「JVM」知识点详解一:JVM运行原理详解

    前言 JVM 一直都是面试的必考点,大家都知道,但是要把它搞清楚又好像不是特别容易.JVM 的知识点太散,不系统,今天带大家详细的了解一下jvm的运行原理. 正文 1 什么是JVM? JVM是Java ...

  10. webpack 快速入门 系列 - 自定义 wepack 上

    其他章节请看: webpack 快速入门 系列 自定义 wepack 上 通过"初步认识webpack"和"实战一"这 2 篇文章,我们已经学习了 webpac ...