关键词:不可变对象 ;匿名对象;new字符串
1、不可变对象
eg1:String s1 = "hello";
s1.toUpperCase();
该例中,调用的该方法并没有改变“hello”的值,而是创建了新的string类“HELLO”;然后将新的实例指向了s1.
2、匿名对象
eg1:String s1 = "hello";
String s2 = "hello";
则我们可以很容易联想到 s1 ==s2;
该例中,在堆内存创建了“hello”,然后在栈内存中,同时创建了两个实例指向了同一个堆内存对象。
3、new字符串
eg1: String s1 = new String("hello");
String s2 = new String("hello");
该例中,利用new 对象同时在堆内存中开辟了两块内存,但都是同一个“hello”的匿名对象,因此在new s2的时候,原来的堆内存则变成垃圾,等待系统回收;
上述举例同时说明了在java中字符串String的特殊性,即不可变特性。每当新建一个字符串对象时,则可在内存中开辟了空间,然后可以直接使用的对象。如果有新实例需要引用该字符串时,不会再内存中重新开辟空间,而是会将该实例直接复用此块内存。减少了不必要的空间开销;
关于String类不可变的优点总结:
1.提高效率和安全性:在拷贝这个对象时,可以直接拷贝该内存地址,这样需要很小的开销,效率也高,同时还不会影响其他指向该String的实例;
2.多线程的安全性:在多线程的情况下,可变对象的值可能会被其他进程改变,造成不可预期的问题,不可变对象则避免了该问题;
3.同时,在创建String类时,它的Hashcode就已经计算好并缓存,不需要重新计算了,因此在使用Map时,将String设置为key效率会远远高于其它的键对象。
进一步:由于String是匿名不可变对象,那么 “+” 和StringBuilder的效率如何呢?
eg:String_s1 +String_s2 ;
StringBuilder sb = new StringBuilder();
sb.append(String_s1);
sb.append(String_s2);
先说“+”: 在内存中,会开辟两块内存分别 存放String_s1 和String_s2.在编译的时候,“+”会变成 new StringBuilder().append(String_s1).append(String_s2).toString(),在最后会调用toString()方法,开辟一块新内存,存放新的String类,最后实例在内存中的指向会发生变化。导致“+”号连接符的效率低下;
而StringBuilder构建的是Builder类,会开辟一个16字符的内存缓冲区,如果后面添加内容大于16字符, Builder会扩充自己的缓冲区,在最后调用toString()时,则会拷贝builder的缓冲区,在内存中形成一个匿名String类,然后新实例会直接指向该区域。
在测试中,我们将0到100000之间的数字全部进行了拼接。分别比较“+”和“StringBuilder”效率,结果是“+”耗时42.67s,Builder耗时0.012s!!!
相关推荐
本文将围绕“java字符串练习”这一主题,深入探讨如何解析字符串、逆序输出字符串以及处理特定格式的字符串数据。 首先,我们要讨论的是字符串解析。在Java中,我们可以使用`String`类提供的方法或正则表达式来实现...
通过运行和调试这些代码,你可以加深对Java字符串、正则表达式以及日期时间格式化的理解。 总之,理解和熟练掌握Java中的字符串操作、正则表达式以及日期时间格式化对于任何Java开发者来说都是必不可少的技能。通过...
首先,我们要明白Java中的字符串是`String`类的对象,它提供了丰富的API用于字符串的处理。例如,我们可以使用`substring()`方法来截取字符串的一部分,但这并不适用于提取括号内的内容,因为我们需要识别开括号和闭...
### Java字符串的编码转换 在Java中,处理不同字符集之间的字符串转换是一项常见任务。尤其是在处理国际化应用时,理解并掌握各种字符编码格式变得尤为重要。下面将介绍几种常见的字符编码格式以及如何在Java中实现...
在Java编程语言中,字符串...以上只是Java字符串操作的一小部分,实际开发中还有许多其他方法和特性,如国际化(I18N)、正则表达式等,都需要程序员灵活掌握。理解并熟练运用这些操作,能有效提高代码质量和效率。
如果需要高效地处理大字符串,可以考虑使用`Pattern`和`Matcher`类,或者使用Java 8引入的流(Stream)API。 另外,`split()`方法会保留分隔符前后的空白字符。如果你不希望这些空白,可以在正则表达式中添加`\b`来...
### Java字符串内存计算 在Java开发中,理解内存管理至关重要,特别是对于字符串处理而言。本文将深入探讨如何在Java中计算字符串所占用的内存空间,包括现有的计算方法、其局限性以及具体的计算公式。 #### 计算...
在Java编程语言中,将字符串转换为16进制ASCII值是一个常见的操作,尤其是在处理数据编码、网络通信或存储时。这个过程涉及到字符到数字的转换,并且通常使用`Character`类和`Integer`类的方法来完成。让我们深入...
本文将深入探讨如何在Java中实现字符串的补0操作,并通过一个具体的示例来说明其实现方法。 #### 二、字符串补0的基本概念 在Java中,字符串补0通常指的是将一个字符串左侧或右侧添加指定数量的字符(通常是“0”)...
在本文中,我们将深入探讨如何使用Java进行字符串分割,以及涉及到的相关知识点。 ### 1. `split()`方法介绍 `split()`方法根据给定的正则表达式将字符串分割成数组。它的基本语法如下: ```java public String[] ...
下面我们将深入探讨如何在Java中分解字符串以及其相关知识点。 1. `split()`方法 `split()`方法是`String`类的一个实例方法,它接受一个正则表达式作为参数,并根据这个正则表达式将字符串分割成一个字符串数组。...
在Java编程语言中,处理字符串是非常常见的操作,尤其是在涉及到文本分析和处理的场景。本文将深入探讨如何在Java中进行中文字符的判断和计数,这主要基于Java的Unicode编码特性以及字符集的理解。 首先,我们需要...
本篇文章将深入探讨Java `String`类的基本概念、特性以及常用方法。 一、String类的声明与初始化 在Java中,`String`是一个不可变的对象,意味着一旦创建,它的值就不能改变。创建`String`对象主要有三种方式: 1....
在Java编程中,"String字符串注入类的静态字段"是一个常见的需求,特别是在初始化配置或设置全局常量时。本文将详细讲解如何实现这一功能,并探讨相关的编程知识点。 首先,我们来看`StringInjector.java`,这个类...
当创建一个新的 String 对象时,Java 会首先在 String.Pool 中查找是否已经存在该字符串,如果存在则返回该字符串的引用,否则创建一个新的字符串对象。 五、String 对象的应用 String 对象是 Java 中最基本的数据...
在Java编程语言中,String类是处理文本字符串的核心类,而与各种进制字符之间的转换是常见的编程需求。本文将详细探讨Java中如何进行String与二进制、八进制、十进制以及十六进制之间的转换。 首先,我们要了解进制...
在Java编程语言中,分割字符串是一项常见的操作,它允许我们将一个长字符串分解成多个子字符串,每个子字符串对应原字符串中的某一部分。这通常通过使用`split()`方法来实现,该方法是`String`类的一个实例方法。让...
本文将深入探讨如何使用Java将对象转换为JSON以及字符串数组。 首先,我们需要一个库来处理JSON转换,这里提到的"json-lib"是一个广泛使用的Java JSON库,提供了多种类型到JSON的转换功能。在Java中,有两种主要...
在Java中,有多种方式来创建字符串对象,如通过`new`关键字、使用`String`字面量或者通过`StringBuffer/StringBuilder`类。例如: ```java String str1 = new String("Hello"); // 使用new关键字 String str2 = ...
本文将深入探讨Java中字符串处理的相关知识点,包括`String`类型的特点、构造方法、字符串操作以及与`StringBuffer`的关系。 #### `String`类型概述 在Java中,`String`类型是不可变的,这意味着一旦一个`String`...