- 浏览: 116992 次
- 性别:
- 来自: 北京
博客专栏
-
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 398http://ifeve.com/sun-misc-unsaf ... -
java 之DelayQueue实际运用示例
2016-06-15 17:09 490http://www.cnblogs.com/sunzhenc ... -
window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法
2015-07-03 19:11 669window下在同一台机器上安装多个版本jdk,修改环境变量不 ... -
java实现base64
2015-04-29 15:30 508BASE64和其他相似的编码算法通常用于转换二进制数据为文本数 ... -
最全的静态网站生成器(开源项目)
2015-04-26 00:53 504最全的静态网站生成器(开源项目) http://www.ite ... -
关于有效的性能调优的一些建议
2015-04-19 12:09 699关于有效的性能调优的 ... -
java 代码时间和内存测试
2015-04-18 22:26 616// 测试用了多少内存 import java.util ... -
系统打印日志的10条建议(翻译)
2015-04-14 14:33 463http://uptoknow.iteye.com/blog/ ... -
Java编程最差实践
2015-04-14 14:32 379http://macrochen.iteye.com/blog ... -
几行代码写RPC
2015-04-13 22:55 444转自梁飞博客 package com.alibaba.stud ... -
58龙哥教你“如何做系统性能优化”(纯干货)
2015-04-12 21:58 584如何做系统性能优化 性能优化的目标是什么?不外乎两个: 时间 ... -
java 关于for和foreach,兼顾效率与安全
2014-12-05 14:46 17360关于for和foreach,兼顾效率与安全 对于数组的访问,是 ... -
java 关于for循环
2014-12-05 14:41 530关于使用for循环 有人喜欢使用for作类似while的循环: ... -
会话COOKIE? 持久COOKIE?
2014-11-07 00:15 555关于COOKIE和SESSION的关系,一直没搞清楚。网上一搜 ... -
内存cookie与持久cookie
2014-11-05 22:27 556cookie分两种 :会话cookie(session coo ... -
Java字符串底层理解
2014-09-11 15:11 7091. 栈(stack)与堆(heap)都是 ... -
java虚拟机垃圾回收深入理解
2013-03-18 17:52 889JAVA学习之4 引用与JVM 1.java内存管理分为内存分 ...
相关推荐
Java字符串长度不够,将其前面补0或者后面补0,适用于字典序比较前,将要比较字符串的位数保持一致,再进行比较。
Java 程序将两个二进制字符串相加
用于测试java字符串几种连接方式的效率,主要包括四类对比测试:1,StringBuffer连接,2,String的Format连接,3,String相加连接,4,StringBuffer的append串起来连接。测试结果如下: String Buffer: 580ms String...
二进制字符串计算器 两个二进制字符串相加的算法。 示例:“01”+“1011”=“1100”
java 倒置字符串 java 倒置字符串
示例 1:输出:"134"示例 2:输出:"533"示例 3:输出:"0"提示:num1 和num2 都只包含数字 0-9num1 和num2 都不包含任何前导
java实现的md5加密实现类对所有的字符串进行加密,加密后生成一串加密后的字符串。
当数字大到不能用long来表示的时候,我们可以用String来表示,这样相乘相加不受位数限制,同时可以用于求大指数,例如pow(2,1000)
主要介绍了JAVA中字符串如何与整型数字相加,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
目录前言String字符串和char字符的区别拓展相互转换String字符串转换成char字符数组char字符转换成String字符串char字符数组转换成String字符串String类和StringBuffer类之间的转换拼接String字符串之间的拼接String...
《Java 程序设计》复习题,方便学习java的同学进行复习。 如果需要考试的话,也是不错的练习题
代码如下: console.log(‘—-1—-‘) console.log(’12’ + ’34’)//’1234′ console.log(’12’ + 34 )//’1234′ console.log(12 + ’34’)//’1234′ console.log(12 + 34 )//46 console.log(‘—-2—-‘) ...
3.用StringBuffer代替字符串相加 4.过滥使用哈希表 5.避免过深的类层次结构和过深的方法调用 6.变量只有在用到它的时候才定义和实例化 7.尽量避免使用static变量,类内私有常量可以用final来代替 8.对频繁使用的...
Java_基础试题及答案 涵盖了JAVA基础试题及答案!
给定一个字符串,找出没有重复字符的最长子字符串的长度。 示例 1: Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. 示例 2: Input: "bbbbb" Output: 1 Explanation: The ...
Java 中的语法糖,真甜 语法糖 泛型 自动拆箱和自动装箱 枚举 内部类 变长参数 增强 for 循环 Switch 支持字符串和枚举 条件编译 断言 try-with-resources 字符串相加 学习语法糖的意义
* 3 将两个字符串对应相加,结果存到到另一个字符串 * 4 最后对新的字符串做进位处理 * @param args */ public static void main(String[] args) { // Scanner input=new Scanner(System.in); // System.out.print(...
包含了货币工具类(将数字货币转成大写)、日期工具类(日期格式化、日期相加减、日期差等)、半角和全角字符相互转换、JSON工具类(利用gson工具包)、字符串工具类(非空判断等)
一、字符串相加这是最容易理解也很常用的一种形式,如下 代码如下:var tmpl =”+ ‘!!! 5’ + ‘html’ + ‘ include header’ + ‘ body’ + ‘ //if IE 6’ + ‘ .alert.alert-error’ + ‘ center ...
2019年Java程序设计100总复习题库及答案,编写一个Java程序,用if-else语句判断某年份是否...编写一个Java应用程序,从键盘读取用户输入两个字符串,并重载3个函数分别实现这两个字符串的拼接、整数相加和浮点数相加。