- 浏览: 125687 次
- 性别:
- 来自: 北京
博客专栏
-
httclient实践与源...
浏览量:0
文章分类
- 全部博客 (141)
- java设计模式 (6)
- oracle (2)
- spring (0)
- java多线程 (12)
- Effective Java 读书笔记 (5)
- mysql (11)
- 书签 (2)
- Web前端 (2)
- python (6)
- 技术博客 (6)
- 搬家 (2)
- android (1)
- java (18)
- 架构 (6)
- linux (14)
- memcached (3)
- 测试 (1)
- 网络 (1)
- 高性能WEB (2)
- http (1)
- java io (2)
- jdbc (1)
- php (5)
- css (2)
- jenkins (1)
- jfinal (1)
- maven (3)
- 算法 (3)
- 代码规范 (1)
- shell (3)
- 安全 (1)
- fastJson源码剖析 (0)
- jdk源码分析 (0)
- git (1)
- 分布式知识点 (0)
- 分布式 (1)
- tcp (1)
- cpu (2)
- 软技能 (1)
- 编译原理 (1)
- 操作系统 (1)
- java虚拟机 (1)
- 处理器 (1)
- tbschedule (1)
- 需要看的源码 (1)
- idea (1)
- zookeeper (1)
- httpclient (1)
最新评论
-
lliiqiang:
功能是关键,但是因为人的性能有限,所以性能也有可能是功能,
关于有效的性能调优的一些建议 -
huangyunbin:
呵呵,感觉和缓存很相似,已经存在的直接缓存里取,缓存没有的话加 ...
享元模式
字符串相加。string + (原作者: 火龙果)
为了加深理解,我们可以来做几个小实验。
javac Test 编译文件
javap -c Test 查看虚拟机指令
实验一:纯字符串
Java code
public class Test {
public static void main(String args[]) {
String str = "a";
}
}
// 将字符串 a 存入常数池
0: ldc #2; //String a
// 将引用存放到 1 号局部变量中
2: astore_1
3: return
实验二:纯字符串相加
Java code
public class Test {
public static void main(String args[]) {
String str = "a" + "b";
}
}
// 将字符串 ab 压入常数池
0: ldc #2; //String ab
2: astore_1
3: return
实验二可以很明显地看出,编译器在编译时产生的字节码已经将 "a" + "b" 优化成了 "ab",
同理多个字符串的相加也会被优化处理,需要注意的是字符串常量相加。
实验三:字符串与自动提升常量相加
Java code
public class Test {
public static void main(String args[]) {
String str = "a" + (1 + 2);
}
}
// 将字符串 a3 压入常数池
0: ldc #2; //String a3
2: astore_1
3: return
通过虚拟机指令可以看出,1 + 2 自动提升后的常量与字符串常量,虚拟机也会对其进行优化。
实验二、实验三结论:常量间的相加并不会引起效率问题
实验四:字符串与变量相加
Java code
public class Test {
public static void main(String args[]) {
String s = "b";
String str = "a" + s;
}
}
// 将字符串 b 压入常数池
0: ldc #2; //String b
// 将引用存放到 1 号局部变量中
2: astore_1
// 检查到非常量的相加,这时创建 StringBuilder 对象
3: new #3; //class java/lang/StringBuilder
// 从栈中复制出数据,即把字符串 b 复制出来 //b 不是在常数池里面吗,这里的栈是指常数池了的栈吗? 还有复制出来,指的是复制到哪里??
6: dup
// 调用 StringBuilder 的初始构造
7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
// 将字符串 a 压入常数池
10: ldc #5; //String a
// 调用 StringBuilder 的 append 方法,把字符串 a 添加进去
12: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
// 从 1 号局部变量中加载数据引用
15: aload_1
// 调用 StringBuilder 的 append 方法,把字符串 b 添加进去
16: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
// 调用 StringBuilder 的 toString 方法
19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
// 将 toString 的结果保存至 2 号局部变量
22: astore_2
23: return
实验四可以看出,非常量字会串相加时,由于相加的变量中存放的是字符串的地址引用,
因为在编译时无法确切地知道其他具体的值,也就没有办法对其进行优化处理,这时为了
达到连接的效果,其内部采用了 StringBuilder 的机制进行处理(JDK 5 中新增的,我
这里没有 JDK 1.4,估计在 JDK 1.4 下采用的是 StringBuffer),将他们都 append
进去,最后用 toString 输出。
若 s 为其他类型时,比如:int 类型,也是采用同种方式进行处理。
同理,根据实验二的结果,在 String str = "a" + "b" + s; 时,先会优化成 "ab" 再与
s 根据实验四的方式进行处理,这时 StringBuilder 仅调用了两次 append 方法。
如果是 String str = "a" + s + "b"; 这种形式的就没办法优化了,StringBuilder 得调
用三次 append 方法。
实验四的结论表明,字符串与变量相加时在内部产生了 StringBuilder 对象并采取了一定
的操作。
如果只有一句 String str = "a" + s; 这样子的,其效率与
String str = new StringBuilder().append("a").append(s).toString();
是一样的。
一般所说的 String 采用连接运算符(+)效率低下主要产生在以下的情况中:
Java code
public class Test {
public static void main(String args[]) {
String s = null;
for(int i = 0; i < 100; i++) {
s += "a";
}
}
}
每做一次 + 就产生个 StringBuilder 对象,然后 append 后就扔掉。下次循环再到达时重
新产生个 StringBuilder 对象,然后 append 字符串,如此循环直至结束。
如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和
销毁对象的时间。
为了加深理解,我们可以来做几个小实验。
javac Test 编译文件
javap -c Test 查看虚拟机指令
实验一:纯字符串
Java code
public class Test {
public static void main(String args[]) {
String str = "a";
}
}
// 将字符串 a 存入常数池
0: ldc #2; //String a
// 将引用存放到 1 号局部变量中
2: astore_1
3: return
实验二:纯字符串相加
Java code
public class Test {
public static void main(String args[]) {
String str = "a" + "b";
}
}
// 将字符串 ab 压入常数池
0: ldc #2; //String ab
2: astore_1
3: return
实验二可以很明显地看出,编译器在编译时产生的字节码已经将 "a" + "b" 优化成了 "ab",
同理多个字符串的相加也会被优化处理,需要注意的是字符串常量相加。
实验三:字符串与自动提升常量相加
Java code
public class Test {
public static void main(String args[]) {
String str = "a" + (1 + 2);
}
}
// 将字符串 a3 压入常数池
0: ldc #2; //String a3
2: astore_1
3: return
通过虚拟机指令可以看出,1 + 2 自动提升后的常量与字符串常量,虚拟机也会对其进行优化。
实验二、实验三结论:常量间的相加并不会引起效率问题
实验四:字符串与变量相加
Java code
public class Test {
public static void main(String args[]) {
String s = "b";
String str = "a" + s;
}
}
// 将字符串 b 压入常数池
0: ldc #2; //String b
// 将引用存放到 1 号局部变量中
2: astore_1
// 检查到非常量的相加,这时创建 StringBuilder 对象
3: new #3; //class java/lang/StringBuilder
// 从栈中复制出数据,即把字符串 b 复制出来 //b 不是在常数池里面吗,这里的栈是指常数池了的栈吗? 还有复制出来,指的是复制到哪里??
6: dup
// 调用 StringBuilder 的初始构造
7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
// 将字符串 a 压入常数池
10: ldc #5; //String a
// 调用 StringBuilder 的 append 方法,把字符串 a 添加进去
12: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
// 从 1 号局部变量中加载数据引用
15: aload_1
// 调用 StringBuilder 的 append 方法,把字符串 b 添加进去
16: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
// 调用 StringBuilder 的 toString 方法
19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
// 将 toString 的结果保存至 2 号局部变量
22: astore_2
23: return
实验四可以看出,非常量字会串相加时,由于相加的变量中存放的是字符串的地址引用,
因为在编译时无法确切地知道其他具体的值,也就没有办法对其进行优化处理,这时为了
达到连接的效果,其内部采用了 StringBuilder 的机制进行处理(JDK 5 中新增的,我
这里没有 JDK 1.4,估计在 JDK 1.4 下采用的是 StringBuffer),将他们都 append
进去,最后用 toString 输出。
若 s 为其他类型时,比如:int 类型,也是采用同种方式进行处理。
同理,根据实验二的结果,在 String str = "a" + "b" + s; 时,先会优化成 "ab" 再与
s 根据实验四的方式进行处理,这时 StringBuilder 仅调用了两次 append 方法。
如果是 String str = "a" + s + "b"; 这种形式的就没办法优化了,StringBuilder 得调
用三次 append 方法。
实验四的结论表明,字符串与变量相加时在内部产生了 StringBuilder 对象并采取了一定
的操作。
如果只有一句 String str = "a" + s; 这样子的,其效率与
String str = new StringBuilder().append("a").append(s).toString();
是一样的。
一般所说的 String 采用连接运算符(+)效率低下主要产生在以下的情况中:
Java code
public class Test {
public static void main(String args[]) {
String s = null;
for(int i = 0; i < 100; i++) {
s += "a";
}
}
}
每做一次 + 就产生个 StringBuilder 对象,然后 append 后就扔掉。下次循环再到达时重
新产生个 StringBuilder 对象,然后 append 字符串,如此循环直至结束。
如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和
销毁对象的时间。
发表评论
-
java Unsafe类
2018-03-20 20:55 464http://ifeve.com/sun-misc-unsaf ... -
java 之DelayQueue实际运用示例
2016-06-15 17:09 549http://www.cnblogs.com/sunzhenc ... -
window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法
2015-07-03 19:11 710window下在同一台机器上安装多个版本jdk,修改环境变量不 ... -
java实现base64
2015-04-29 15:30 548BASE64和其他相似的编码算法通常用于转换二进制数据为文本数 ... -
最全的静态网站生成器(开源项目)
2015-04-26 00:53 555最全的静态网站生成器(开源项目) http://www.ite ... -
关于有效的性能调优的一些建议
2015-04-19 12:09 796关于有效的性能调优的 ... -
java 代码时间和内存测试
2015-04-18 22:26 653// 测试用了多少内存 import java.util ... -
系统打印日志的10条建议(翻译)
2015-04-14 14:33 531http://uptoknow.iteye.com/blog/ ... -
Java编程最差实践
2015-04-14 14:32 423http://macrochen.iteye.com/blog ... -
几行代码写RPC
2015-04-13 22:55 479转自梁飞博客 package com.alibaba.stud ... -
58龙哥教你“如何做系统性能优化”(纯干货)
2015-04-12 21:58 620如何做系统性能优化 性能优化的目标是什么?不外乎两个: 时间 ... -
java 关于for和foreach,兼顾效率与安全
2014-12-05 14:46 17500关于for和foreach,兼顾效率与安全 对于数组的访问,是 ... -
java 关于for循环
2014-12-05 14:41 592关于使用for循环 有人喜欢使用for作类似while的循环: ... -
会话COOKIE? 持久COOKIE?
2014-11-07 00:15 585关于COOKIE和SESSION的关系,一直没搞清楚。网上一搜 ... -
内存cookie与持久cookie
2014-11-05 22:27 592cookie分两种 :会话cookie(session coo ... -
Java字符串底层理解
2014-09-11 15:11 7861. 栈(stack)与堆(heap)都是 ... -
java虚拟机垃圾回收深入理解
2013-03-18 17:52 950JAVA学习之4 引用与JVM 1.java内存管理分为内存分 ...
相关推荐
Java字符串长度不够,将其前面补0或者后面补0,适用于字典序比较前,将要比较字符串的位数保持一致,再进行比较。
在本压缩包“java-leetcode题解之第415题字符串相加.zip”中,包含的是关于LeetCode第415题“字符串相加”(Add Strings)的Java解决方案。这道题目属于计算机编程领域,特别是Java语言的学习与算法实践。LeetCode是...
用于测试java字符串几种连接方式的效率,主要包括四类对比测试:1,StringBuffer连接,2,String的Format连接,3,String相加连接,4,StringBuffer的append串起来连接。测试结果如下: String Buffer: 580ms String...
在Java编程中,将两个二进制字符串相加是一个常见的任务,这通常涉及到将字符串转换为整数,进行加法运算,然后将结果转换回二进制字符串。下面我们将详细探讨两种实现方法。 方法一: 这种方法是通过首先将二进制...
本文将深入探讨如何实现一个二进制字符串计算器,以完成将两个二进制字符串相加的任务。我们将主要关注Java编程语言,因为这是给定的标签。 首先,我们需要了解二进制字符串的基本概念。二进制是计算机内部处理数据...
在Java编程语言中,倒置字符串是一个常见的任务,它涉及到将一个给定的字符串的字符顺序反转。在本文中,我们将深入探讨如何在Java中实现这个功能,...同时,了解这些不同的实现方式有助于加深对Java字符串操作的理解。
示例 1:输出:"134"示例 2:输出:"533"示例 3:输出:"0"提示:num1 和num2 都只包含数字 0-9num1 和num2 都不包含任何前导
本节主要探讨的是Python中的数字类型转换以及与字符串类型的交互。 首先,Python支持三种基本的数字类型:整数(int)、浮点数(float)和布尔型(bool)。布尔型实际上可以被视为整数的子类型,其中`True`相当于`1...
### Java 实验知识点详解 #### 一、设计图形软件包 根据题目要求,我们需要设计一个图形软件包,其中包含三个类:三角形类、...此外,还涉及了字符串处理和数组操作的基础知识,这些都是Java编程的重要组成部分。
Java 基本语法—字符串与数值型数据转换、从键盘输入数据 本实验报告主要讲述了 Java 基本语法中字符串与数值型数据转换、从键盘输入数据的相关知识点。下面是本实验报告的详细内容: 一、实验目的 在本实验中,...
JAVA中字符串与整型数字相加 在 Java 编程语言中,字符串与整型数字相加是一种常见的操作。然而,对于初学者而言,如何正确地将字符串与整型数字相加却是一个难题。本文将详细介绍 Java 中字符串与整型数字相加的...
MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,它能够将任意长度的输入数据转换为固定长度的输出,通常是32位的十六进制字符串。在IT行业中,MD5主要用于数据完整性校验和简单的密码加密。 MD5算法...
2. **add 方法**:此方法实现了两个字符串表示的数字相加。首先调用 `null2zero` 方法处理输入,然后创建两个 `BigDecimal` 对象并使用 `add` 方法计算它们的和,最后返回结果的字符串表示。 3. **add2 方法**:这...
例如,输入字符串"2 + 3 * 4"需要被解析为两个操作:首先计算括号内的3 * 4,然后将结果与2相加。解析器通常使用**词法分析**(lexing)和**语法分析**(parsing)来完成这项工作。词法分析将输入分解成一个个称为...
Java字符拼接成字符串的注意点详解 在Java中,字符拼接成字符串是一个常见的操作,但是很多开发者并不知道在拼接字符时的一些注意点。今天,我们将详细介绍Java字符拼接成字符串的注意点详解。 1. 字符与ASCII码的...
当数字大到不能用long来表示的时候,我们可以用String来表示,这样相乘相加不受位数限制,同时可以用于求大指数,例如pow(2,1000)
JAVA字符串类型switch的底层原理详析 JAVA字符串类型switch的底层原理详析是指在JAVA语言中,switch语句是如何处理字符串类型的表达式的。从表面上看,switch语句似乎可以直接处理字符串类型的表达式,但是实际上,...
这是最简单的方法,只需将 Long 变量与空字符串 "+" 相加,即可完成转换。例如: ```java String str = varLong + " "; ``` 这会导致自动装箱(Long 转成 Long 对象)并调用 Long 的 toString() 方法,然后通过拼接...
符之间的拼接字符之间的拼接在Java中,String与char之间的拼接主要涉及到字符串与单个字符的相互转换。以下是一些示例: 1. String字符串转换为char字符: - 如果想要将一个String字符串中的单个字符提取出来,...