String类中你不知道的知识

直接量创建对象更高效

在Java中,创建一个字符串有两种方法:

//第一种方法
String str1 = "字符串1";
//第二种方法
String str2 = new String("字符串2");

这两种方式创建的字符串在使用上并无区别,但在内存分配方式上完全不同,而且效率大相径庭。下面详细阐述:

第一种方式:

这种方式创建的字符串对象在堆内存中只需要一块存储空间。系统只需在字符串缓冲池中创建该字符串,并将str1指向该字符串对象。

第二种方式:

首先创建String类型的对象,再在字符串缓冲池中创建“字符串2”,并将String类型对象指向“字符串2”,再将str2指向String类型对象。

因此,第一种方式只在堆内存中开辟了一个存储空间,第二种方式在堆内存中开辟了两块存储空间。因此,第一种方式更高效。

在Java中,所有基本数据类型和String类型都有这两种创建对象的方式,我们把第一种方式称为“使用直接量创建对象”。因此,在Java中,使用直接量创建对象更高效!

字符串缓冲池是什么?

它存在于堆内存中,用于存储JVM运行以来所有出现过的字符串对象。

当系统需要创建字符串时,首先判断该字符串是否存在于缓冲池中,若存在则无需创建直接引用,否则创建该字符串。因此,采用直接量方式创建的两个字符串对象是相同的:

String str1 = "字符串";
String str2 = "字符串";
System.out.println(str1==str2);//结果为true!str1和str2均引用字符串缓冲池中的同一个对象

字符串经典面试题

问:下面程序输出结果是什么?

String str1 = "我是个大好人6";
String str2 = "我是个"+"大好人"+6;
System.out.println(str1==str2);

输出结果为true!

等号右侧的两个值均在编译时确定下来,因此它们均引用字符串缓冲池中的同一个对象。

问:下面程序输出结果是什么?

String str1 = "我是个大好人6";
String str2 = "我是个大好人"+"我是个大好人".length();
int len = 6;
String str3 = "我是个大好人"+len;
System.out.println(str1==str2);
System.out.println(str1==str3);

结果均为false!

由于str2和str3中含有变量或调用了函数,所以str2、str3等号右侧的值在运行阶段才能阶段确定下来,因此它们无法利用字符串缓冲池中的“我是个大好人6”。

问:下面程序输出结果是什么?

String str1 = "我是个大好人6";
final int len = 6;
String str2 = "我是个大好人"+len;
System.out.println(str1==str2);

结果为true!

此时len被final修饰,len的值固定为6不会发生变化,因此在编译时可以确定str2等号右侧的值为“我是个大好人6”,因此仍然可以沿用字符串池中的“我是个大好人6”。

问:下列程序在字符串缓冲池中创建了几个常量?

String str = "我是个"+"大好人"+6;

答案为1个!

该字符串中不包含变量和方法,因此在编译时即可确定,编译器看来就是一个完整的常量“我是个大好人6”

问:下列程序在字符串缓冲池中创建了几个常量?

String str = "我是个";
str = str + "大好人";

答案为2个!

在执行第一行代码时,常量池中创建“我是个”,执行第二行代码时,常量池中再创建“我是个大好人”,并切断str与“我是个”的引用,指向“我是个大好人”,而常量“我是个”继续留在常量池中。

    由于缓冲池中的字符串一般不会被垃圾回收,因此通过这种拼接的方式创建的字符串将会在常量池产生很多碎片,而StringBuffer和StringBuilder就是为了这种问题而诞生的!

    如果一个字符串需要不断发生修改,则使用StringBuffer和StringBuilder比String更加高效。

    StringBuilder是线程安全的,因为在其绝大多数方法都是同步方法,但因此其效率较低;

    综上所述,若程序涉及多线程,应选用StringBuilder;若单线程,则选择StringBuffer效率更高。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

3565
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2997
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

3356
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

28610
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4394
来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

4769
来自专栏落花落雨不落叶

canvas画简单电路图

1.1K12
来自专栏跟着阿笨一起玩NET

c#实现打印功能

4832
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

3730
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

6367

扫码关注云+社区