- 浏览: 738020 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
18335864773:
看了楼主写的用jxl生成excel。有地方用到了流,还特别强调 ...
jxl导出excel文件简单示例 -
shaoshou111:
查看Apache的并发请求数及其TCP连接状态netstat ...
Linux查看连接数,并发数 -
gengjunshi:
非常感谢哈,刚好在学webservice编程,很有用呢。
JAX-WS开发webservice示例详解 -
zcgewu:
encrypt2()和encrypt()有什么区别
JAVA实现AES加密 -
java爱好者92:
ireport的操作还是相对比较复杂的,帆软报表会相对简单一点 ...
iReport报表开发中常见的问题
非可变对象一旦创建之后就不能再被改变,可变对象则可以在创建之后被改变。String对象是非可变对象;StringBuffer对象则是可变对象。为获得更佳的性能需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。
String类用来表示那些创建后就不会再改变的字符串,它是不可变的(immutable);
StringBuffer类用来表示内容可变的字符串;
例:
1.String对象:
// JVM会创建一个临时的StringBuffer类对象,并调用其append()方法完成字符串的拼接,这是因为 String类是不可变的,拼接操作不得不使用StringBuffer类(并且--JVM会将"Hello"和"World"创建为两个新的 String对象)。之后,再将这个临时StringBuffer对象转型为一个String,代价不菲!可见,在这一个简单的一次拼接过程中,我们让程 序创建了四个对象:两个待拼接的String,一个临时StringBuffer,和最后将StringBuffer转型成为 的String--它不是最初的str,而是最初的str的引用指向了新生成的String对象"HelloWorld"。
2.StringBuffer对象:
// 程序将只产生两个对象:最初的strBuf :"Hello"和拼接时的String("World"),不再需要创建临时的StringBuffer类对象而后还得将其转换回String对象。节省额外的系统开销。
如何选择是使用String还是StringBuffer:
取决于两种情况,第一种情况是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情况是你使用的是StringBuffer还是String。
1) 第一种情况:编译期决定相对于运行期决定;如:
此时,+操作符比StringBuffer.append()方法要快,WHY?这里编译器的优化起了关键作用,编译器简单地在编译期连接多个字符串。 它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。这里str对象在编译期就决定了而 StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作糜谧址 闹悼梢栽は戎 赖氖?候,也就是说String str = "This " + "is " + "a " + "Java " + "program";这段代码在编译时,编译器会对程序作出优化,String str被优化成“This is a Java program”;而StringBuffer strBuf只会在运行时才处理。所以效率是不一样的。(注意,这里的String str = "This " + "is " + "a " + "Java " + "program";与 String str = "Hello";
str += "World";是不一样的);
2) 第二种情况:使用StringBuffer取代String
此时,StringBuffer.append()方法要比+操作符快得多,WHY?原因是两者都是在运行期决定字符串对 象,但是+操作符使用不同于StringBuffer.append()的规则;它是通过String和StringBuffer来完成字符串的连接操作 的。
另外,在使用StringBuffer时,可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函 数是StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。如:
(1):
(2):
此时,(2) 的效率好于 (1),因为StringBuffer内部实现是char数组,当使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符 长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候,它会将自 身容量增加到当前的2倍再加2,也就是(2*旧值+2)。 如果使用缺省值,初始化之后接着往里面追加字符,在追加到第16个字符的时候它会将容量增加到 34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容量它就不得 不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿 见影的性能增益。(2)避免了复制数组的开销。
创建String对象:
String str = "Hello";
// JVM先根据内容"Hello"查找对象,如果没找到,则在heap(堆栈)*上创建新对象,并将其赋予str,否则使用已经存在的对象。
String str = new String("Hello");
// 据内不管heap上有没有"Hello"这个对象,JVM都会在heap上创建一个新String对象;此时heap上可能会出现内容相同,地址不同的String对象。
推荐使用String str = "Hello";这种方法创建String类型的对象,这样会使heap中只存在唯一的一个存放"Hello"对象的内存地址;实际上我们不需要多个独立的"Hello"对象,因为要运行它们的话浪费时间+浪费内存。我们也不必因使用new String("Hello");创 建了多个”Hello”对象而发愁,可以使用intern()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。String intern()方法检查字符串对象的存在性,如果需要的字符串已经存在,那么它将会引用指向已经存在的字符串对象而不是重新创建一个。这和使用 String str = "Hello";这种方法创建对象就作用上来说是一致的。使用intern():
String对象的比较
但是StringBuffer类并没有实现Objcet类的Equals方法,所以不能用这个方法来比较两个StringBuffer类的字符串是否相等:
程序输出:false
*这里想对“heap(堆栈)”做一下更正:应该是heap(堆),而非堆栈。
“堆”是一种通用的内存池,用于存放所有的Java对象。当使用“new”实例化一个对象时,编译器会自动在堆里进行存储分配。
C++在堆栈中创建对象,Java对象引用存储在堆栈中;而Java对象并不存储于其中。
堆栈:堆栈指针向下移动,分配新内存,向上移动,释放内存;创建程序时编译器必须知道存储在堆栈中所有数据的确切大小和生命周期,因为要通过代码实现来控制上下移动堆栈指针,这一约束限制了程序的灵活性。而如果是在堆上创建对象,编译器不需要知道从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。
String类用来表示那些创建后就不会再改变的字符串,它是不可变的(immutable);
StringBuffer类用来表示内容可变的字符串;
例:
1.String对象:
String str = "Hello"; str += "World";
// JVM会创建一个临时的StringBuffer类对象,并调用其append()方法完成字符串的拼接,这是因为 String类是不可变的,拼接操作不得不使用StringBuffer类(并且--JVM会将"Hello"和"World"创建为两个新的 String对象)。之后,再将这个临时StringBuffer对象转型为一个String,代价不菲!可见,在这一个简单的一次拼接过程中,我们让程 序创建了四个对象:两个待拼接的String,一个临时StringBuffer,和最后将StringBuffer转型成为 的String--它不是最初的str,而是最初的str的引用指向了新生成的String对象"HelloWorld"。
2.StringBuffer对象:
StringBuffer strBuf = new StringBuffer("Hello"); strBuf.append("World");
// 程序将只产生两个对象:最初的strBuf :"Hello"和拼接时的String("World"),不再需要创建临时的StringBuffer类对象而后还得将其转换回String对象。节省额外的系统开销。
如何选择是使用String还是StringBuffer:
取决于两种情况,第一种情况是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情况是你使用的是StringBuffer还是String。
1) 第一种情况:编译期决定相对于运行期决定;如:
String str = "This " + "is " + "a " + "Java " + "program"; StringBuffer strBuf = new StringBuffer(); strBuf.append("This "); strBuf.append("is "); strBuf.append("a "); strBuf.append("Java "); strBuf.append("program");
此时,+操作符比StringBuffer.append()方法要快,WHY?这里编译器的优化起了关键作用,编译器简单地在编译期连接多个字符串。 它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。这里str对象在编译期就决定了而 StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作糜谧址 闹悼梢栽は戎 赖氖?候,也就是说String str = "This " + "is " + "a " + "Java " + "program";这段代码在编译时,编译器会对程序作出优化,String str被优化成“This is a Java program”;而StringBuffer strBuf只会在运行时才处理。所以效率是不一样的。(注意,这里的String str = "This " + "is " + "a " + "Java " + "program";与 String str = "Hello";
str += "World";是不一样的);
2) 第二种情况:使用StringBuffer取代String
String str = "Hello"; for(int i = 0; i < 40000; i++) { str += "World"; } StringBuffer strBuf = new StringBuffer("Hello"); for(int i = 0; i < 40000; i++) { strBuf.append("World"); }
此时,StringBuffer.append()方法要比+操作符快得多,WHY?原因是两者都是在运行期决定字符串对 象,但是+操作符使用不同于StringBuffer.append()的规则;它是通过String和StringBuffer来完成字符串的连接操作 的。
另外,在使用StringBuffer时,可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函 数是StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。如:
(1):
StringBuffer strBuf = new StringBuffer(); for(int i = 0; i < 40000; i++) { strBuf.append("Hello"); }
(2):
StringBuffer strBuf = new StringBuffer(100000); for(int i = 0; i < 40000; i++) { strBuf.append("Hello"); }
此时,(2) 的效率好于 (1),因为StringBuffer内部实现是char数组,当使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符 长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候,它会将自 身容量增加到当前的2倍再加2,也就是(2*旧值+2)。 如果使用缺省值,初始化之后接着往里面追加字符,在追加到第16个字符的时候它会将容量增加到 34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容量它就不得 不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿 见影的性能增益。(2)避免了复制数组的开销。
创建String对象:
String str = "Hello";
// JVM先根据内容"Hello"查找对象,如果没找到,则在heap(堆栈)*上创建新对象,并将其赋予str,否则使用已经存在的对象。
String str = new String("Hello");
// 据内不管heap上有没有"Hello"这个对象,JVM都会在heap上创建一个新String对象;此时heap上可能会出现内容相同,地址不同的String对象。
推荐使用String str = "Hello";这种方法创建String类型的对象,这样会使heap中只存在唯一的一个存放"Hello"对象的内存地址;实际上我们不需要多个独立的"Hello"对象,因为要运行它们的话浪费时间+浪费内存。我们也不必因使用new String("Hello");创 建了多个”Hello”对象而发愁,可以使用intern()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。String intern()方法检查字符串对象的存在性,如果需要的字符串已经存在,那么它将会引用指向已经存在的字符串对象而不是重新创建一个。这和使用 String str = "Hello";这种方法创建对象就作用上来说是一致的。使用intern():
String str = new String("Hello"); str = str.intern();
String对象的比较
"==" //比较地址; "equals" //比较内容; String str1 = "a"; String str2 = "a"; String str3 = new String("a"); str1 == str2 // true str1 == str3 // false str1.equals(str2); // true str1.equals(str3); // true
但是StringBuffer类并没有实现Objcet类的Equals方法,所以不能用这个方法来比较两个StringBuffer类的字符串是否相等:
StringBuffer strBuf1 = new StringBuffer(“a”); StringBuffer strBuf2 = new StringBuffer(“a”); System.out.println(strBuf1.equals(strBuf2));
程序输出:false
*这里想对“heap(堆栈)”做一下更正:应该是heap(堆),而非堆栈。
“堆”是一种通用的内存池,用于存放所有的Java对象。当使用“new”实例化一个对象时,编译器会自动在堆里进行存储分配。
C++在堆栈中创建对象,Java对象引用存储在堆栈中;而Java对象并不存储于其中。
堆栈:堆栈指针向下移动,分配新内存,向上移动,释放内存;创建程序时编译器必须知道存储在堆栈中所有数据的确切大小和生命周期,因为要通过代码实现来控制上下移动堆栈指针,这一约束限制了程序的灵活性。而如果是在堆上创建对象,编译器不需要知道从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。
发表评论
-
nginx反向代理后,打开页面很慢
2020-05-26 11:26 5275nginx反向代理后,打开页面很慢 在做前后端完全分离的 ... -
【国】前后端国际化的问题
2020-04-23 17:21 1085前端有国际化,但是后端service无法使用国际化。 原 ... -
(转)Java jacob调用打印机打印word文档
2017-12-01 17:33 3834折腾了好久,最终决定由用一个第三方的,找到了jacob,还不 ... -
BIRT参数设置详解
2016-05-18 15:15 4448在使用birt报表的时候感 ... -
gson的使用分享
2016-01-15 13:48 1876一、 最基本的对象与JSON相互转换 1、 定义java对象 ... -
(转)FindBugs规则整理
2015-12-18 10:40 6666FindBugs是基于Bug Patterns ... -
Gson注解和GsonBuilder
2015-04-07 11:49 1724//注意这里的Gson的构建方式为GsonBuilder, ... -
javax.xml.ws.soap.SOAPFaultException: Cannot create a secure XMLInputFactory
2014-06-04 20:26 1878javax.xml.ws.soap.SOAPFaultExce ... -
照片打包下载
2014-05-22 09:32 1270设计思路: 通过业务表中照片编号获得需要下载的照片列表 ... -
Oracle merge 合并
2013-10-21 09:38 1348@Transactional public void ... -
httpclient测试请求方法
2013-09-22 15:24 3725貌似很多人不知道服务器端代码怎么写,在此mark一下: ... -
jxl导入excel
2013-09-17 16:56 966jxl读取excel和写excel基本类似,只是Writab ... -
findbugs清理总结
2013-08-19 14:45 3046findbugs警告26个。主要有以下9类问题。 1、B ... -
JAX-WS开发webservice示例详解
2013-08-09 11:06 24138目录: 概述 实验环境 服务端的实现 客户端的实 ... -
将传进来的十六进制表示的字符串转换成byte数组 文件下载
2013-06-06 22:36 1826/** * 将传进来的十六进制表示的字符串转换成by ... -
Java:定时启动线程及线程池的用法
2013-05-23 18:01 4028这里提供两种在指定时间后启动线程的方法。一是通过java.ut ... -
依赖倒转原则
2013-04-13 12:31 1021A、高层模块不应该依赖低层模块,两个都应该依赖抽象。 B、抽象 ... -
策略模式
2013-04-12 17:31 1040策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替 ... -
调用xfire发布的wsdl遇到的问题
2013-02-20 14:25 1174java.lang.NoClassDefFoundError ... -
(转)在java中通过JDBC连接Oracle,ResultSet返回总为空,这个问题是怎么解决呢
2013-01-08 10:38 16458数据库基本访问格式 Class.forName(“JDBC驱动 ...
相关推荐
在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...
"String StringBuffer和StringBuilder区别之源码解析" 在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、...
在Java编程语言中,`String`、`...理解`String`、`StringBuffer`和`StringBuilder`的区别和使用场合,可以帮助开发者写出更高效、更安全的代码。在实际开发中,应根据项目需求和环境选择合适的字符串处理类。
#### 二、String与StringBuffer的区别 1. **可变性**:`String`对象是不可变的,而`StringBuffer`对象是可变的。 2. **性能**:对于频繁修改的字符串,使用`StringBuffer`会比不断创建新`String`对象更加高效。 3. ...
stringbuilder用法 String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String...
在Java编程语言中,`String`和`StringBuffer`都是用来表示和操作字符串的重要类,但它们在性能和使用场景上有显著的区别。 首先,`String`类是不可变的,这意味着一旦创建了一个`String`对象,它的内容就不能改变。...
Java中的String、StringBuilder和StringBuffer类都是用于处理字符串的,但在不同的场景下,它们各有优缺点。本篇文章将深入分析这三个类的区别。 首先,我们来看它们的值可变性。String类是不可变的,这意味着一旦...
在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的重要类,它们各自有特定的使用场景和特性。理解这三个类的区别对于任何Java开发者,无论是初学者还是经验丰富的程序员,都是非常重要的...
1. **单线程环境**:在这种情况下,推荐使用 **StringBuilder**,因为它不提供线程安全机制,所以在性能上优于 StringBuffer 和 String。 2. **多线程环境**: - 如果需要修改字符串内容,则应选择 **...
在Java编程语言中,`String`和`StringBuffer`都是用来表示和操作字符串的重要类,但它们在使用场景和性能上有显著的区别。了解这些差异对于编写高效、优化的代码至关重要。 首先,`String`类是不可变的。这意味着...
在Java编程语言中,`String`和`StringBuffer`(在Java 5之后被`StringBuilder`取代,但在多线程环境中仍然使用`StringBuffer`)是处理文本字符串的两个核心类,它们各自有着不同的特性和用途。理解它们的区别对于...
它们之间的主要区别在于可变性、性能和使用场景。 1. **不可变性**: `String`类是不可变的,这意味着一旦创建了一个`String`对象,它的内容就不能被修改。每次对`String`对象进行操作(如拼接、替换字符等),...
这里展示了使用`+=`与`StringBuffer`的`append()`方法的区别。使用`+=`时,每次操作都会创建新的字符串对象,而`StringBuffer`则是在原对象上进行修改,从而避免了不必要的对象创建。 ### 总结 - 在单线程环境中,...
在 Java 中,String, StringBuffer 和 StringBuilder 三个类都是用于字符操作的,但它们之间有着很大的区别。 首先,String 是不可变类,意味着一旦创建了 String 对象,就不能修改它的值。每次对 String 对象的...
在Java编程语言中,`String`与`StringBuffer`是两个重要的字符串处理类,它们各自具有独特的特性和用途,尤其在面试或笔试中常被提及作为考察应聘者对Java基础知识掌握程度的重要知识点。 ### `String`类:不可变性...
在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们之间存在显著的差异,主要体现在性能、线程安全性和使用场景上。 首先,`String`是最基本的字符串类,它代表的是不可...
这里我们将深入探讨这三个类的区别、特性和使用策略。 首先,String类是不可变的,这意味着一旦创建了一个String对象,就不能再更改它的值。每次对String对象进行修改(如使用“+”进行拼接)时,实际上都会创建一...
在这个示例中,我们比较了使用 `String` 和 `StringBuffer` 进行 5000 次字符串拼接的执行时间。根据实际运行结果,我们可以发现 `StringBuffer` 的执行时间明显短于 `String`,尤其是在大量字符串拼接的情况下。 #...