String类源码分析:
- String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被 final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。在早期的JVM实现版本中,被final修饰的方法会被转为内嵌调用 以提升执行效率。而从Java SE5/6开始,就渐渐摈弃这种方式了。因此在现在的Java SE版本中,不需要考虑用final去提升方法调用效率。只有在确定不想让该方法被覆盖时,才将方法设置为final。
- String类中char value[],int offset,int count,int hash成员属性,可以看出String类其实是通过char数组来保存字符串的。
- 从String类提供的方法比如subString,concat,replace等操作都算不是在原有的字符串对象上进行操作,subString是新new一个String对象,后两个都是新new一个char 数组,也就是说进行这些操作后,最原始的字符串并没有被改变。
特别提醒:对String对象的任何改变都不影响到原对象,相关的任何修改操作都会生成新的对象。
String StringBuffer StringBuilder的区别;
在 系统里面String可以满足任何操作,为什么还要有StringBuffer和StringBuilder类,给大家看段代码我想会更清楚的表达出来。
public class Main { public static void main(String[] args) { String string = ""; for(int i=0;i<10000;i++){ string += "hello"; } } }
我想这段代码大家很清楚就明白是什么意识,无非就是字符串循环相加,这样理解是没有错误的,在上面我们通过String类了解过,String类的任何操作都是新new一个对象, 而不是在原有的基础上进行相加,比如:string +="hello"这句话,如果10000次,那么就要创建10000个新StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象。也就 是说这个循环执行完毕new出了10000个对象,试想一下,如果这些对象没有被回收,会造成多大的内存资源浪费。从上面还可以看 出:string+="hello"的操作事实上会自动被JVM优化成:
StringBuilder str = new StringBuilder(string);
str.append("hello");
str.toString();
为了验证我的推理是正确的,可以通过如下代码进行验证:
public class Main { private static int time = 50000; public static void main(String[] args) { testString(); testOptimalString(); } public static void testString () { String s=""; long begin = System.currentTimeMillis(); for(int i=0; i<time; i++){ s += "java"; } long over = System.currentTimeMillis(); System.out.println("操作"+s.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒"); } public static void testOptimalString () { String s=""; long begin = System.currentTimeMillis(); for(int i=0; i<time; i++){ StringBuilder sb = new StringBuilder(s); sb.append("java"); s=sb.toString(); } long over = System.currentTimeMillis(); System.out.println("模拟JVM优化操作的时间为:"+(over-begin)+"毫秒"); } }
运行结果为:
操作java.lang.String类型使用的时间为:3194毫秒 模拟JVM优化操作的时间为:3197毫秒
如果系统中很多地方都这样进行拼接,这将是计算机的灾难,为了提高字符串拼接的性能,让我们看一段StringBuilder的代码:
public class Main { public static void main(String[] args) { StringBuilder stringBuilder = new StringBuilder(); for(int i=0;i<10000;i++){ stringBuilder.append("hello"); } } }
从这里可以明显看出,这段代码的for循环开始到结束只进行了new操作,创建一个StringBuilder对象,字符串拼接都是通过append操作是在原有对象的基础上进行的。因此在循环了10000次之后,这段代码所占的资源要比上面小得多。有人有说了,既然StringBuilder可以提高字符串拼接的性能,那么怎么还要有StringBuffer,让我们在来看一段代码你就会明白。
StringBuilder 的insert操作代码 public StringBuilder insert(int index, char str[], int offset, int len){ super.insert(index, str, offset, len); return this; } StringBuffer 的insert操作代码 public synchronized StringBuffer insert(int index, char str[], int offset, int len){ super.insert(index, str, offset, len); return this; }
通过两段代码可以发现就是StringBuffer比StringBuilder多了一个synchronized多了一把锁,也就是说StringBuffer是线程安全的。
String StringBuffer StringBuilder的性能;
讲过这三个方法的区别,通过程序来区别一下这三个类的性能,到底哪个性能更好些。
public class test { private static int longCount = 50000; public static void main(String[] args) { testString(); testStringBuffer(); testStringBuilder(); test1String(); test2String(); } public static void testString () { String s=""; long begin = System.currentTimeMillis(); for(int i=0; i<longCount; i++){ s += "java"; } long over = System.currentTimeMillis(); System.out.println("操作"+s.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒"); } public static void testStringBuffer () { StringBuffer sb = new StringBuffer(); long begin = System.currentTimeMillis(); for(int i=0; i<longCount; i++){ sb.append("java"); } long over = System.currentTimeMillis(); System.out.println("操作"+sb.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒"); } public static void testStringBuilder () { StringBuilder sb = new StringBuilder(); long begin = System.currentTimeMillis(); for(int i=0; i<longCount; i++){ sb.append("java"); } long over = System.currentTimeMillis(); System.out.println("操作"+sb.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒"); } public static void test1String () { long begin = System.currentTimeMillis(); for(int i=0; i<longCount; i++){ String s = "I"+"love"+"java"; } long over = System.currentTimeMillis(); System.out.println("字符串直接相加操作:"+(over-begin)+"毫秒"); } public static void test2String () { String s1 ="I"; String s2 = "love"; String s3 = "java"; long begin = System.currentTimeMillis(); for(int i=0; i<longCount; i++){ String s = s1+s2+s3; } long over = System.currentTimeMillis(); System.out.println("字符串间接相加操作:"+(over-begin)+"毫秒"); } }
运行结果为:
操作java.lang.String类型使用的时间为:3149毫秒 操作java.lang.StringBuffer类型使用的时间为:3毫秒 操作java.lang.StringBuilder类型使用的时间为:2毫秒 字符串直接相加操作:1毫秒 字符串间接相加操作:8毫秒
下面对上面的执行结果进行一般性的解释:
1)对于直接相加字符串,效率很高,因为在编译器便确定了它的值,也就是说形如"I"+"love"+"java"; 的字符串相加,在编译期间便被优化成了"Ilovejava"。这个可以用javap -c命令反编译生成的class文件进行验证。对于间接相加(即包含字符串引用),形如s1+s2+s3; 效率要比直接相加低,因为在编译器不会对引用变量进行优化。
2)String、StringBuilder、StringBuffer三者的执行效率:
StringBuilder > StringBuffer > String
当然这个是相对的,不一定在所有情况下都是这样。
比如String str = "hello"+ "world"的效率就比 StringBuilder st = new StringBuilder().append("hello").append("world")要高。
因此,这三个类是各有利弊,应当根据不同的情况来进行选择使用:
当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;
当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。
相关推荐
"String StringBuffer和StringBuilder区别之源码解析" 在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、...
StringBuffer:字符创变量 StringBuilder:字符创变量 从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...
在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的类,但它们之间存在显著的性能和功能差异。下面我们将深入探讨这三个类的区别。 首先,`String`类是Java中最基本的字符串类型,它表示...
在Java编程语言中,`String`、`...理解`String`、`StringBuffer`和`StringBuilder`的区别和使用场合,可以帮助开发者写出更高效、更安全的代码。在实际开发中,应根据项目需求和环境选择合适的字符串处理类。
在 Java 中,String, StringBuffer 和 StringBuilder 三个类都是用于字符操作的,但它们之间有着很大的区别。 首先,String 是不可变类,意味着一旦创建了 String 对象,就不能修改它的值。每次对 String 对象的...
String、StringBuffer 和 StringBuilder 是 Java 语言中三种不同类型的字符串处理方式,它们之间存在着明显的性能和线程安全性差异。 String String 类型是不可变的对象,每次对 String 对象进行改变时都会生成一...
Java 中 String, StringBuffer 与 StringBuilder 的区别 Java 中 String, StringBuffer 与 StringBuilder 三种字符串类型的区别是很多开发者经常混淆或不了解的知识点。今天,我们将深入探讨这三种字符串类型的区别...
在Java编程语言中,String和StringBuilder是两个非常重要的类,它们在处理文本字符串时起着核心作用。了解这两个类的特点和使用场景对于提高程序性能至关重要。 首先,`String`类在Java中是不可变的,这意味着一旦...
在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们之间存在显著的差异,主要体现在性能、线程安全性和使用场景上。 首先,`String`是最基本的字符串类,它代表的是不可...
"Java 中 String、StringBuffer 和 StringBuilder 的区别及用法" Java 中 String、StringBuffer 和 StringBuilder 是三个常用的字符串操作类,了解它们之间的区别对 Java 开发者来说非常重要。本文将详细介绍这三者...
Java中的字符串处理是编程中常见的任务,涉及到三个关键类:String、StringBuffer和StringBuilder。它们在功能上相似,但有着重要的区别,主要体现在字符串的可变性、线程安全性和性能方面。 1. 可变性 - String类...
Java 中 String 和 StringBuffer 与 StringBuilder 的区别及使用方法 Java 中 String、StringBuffer 和 StringBuilder 是三个常用的字符串操作类,每个类都有其特点和使用场景。在开发过程中,正确选择合适的字符串...
在 Java 中,String、StringBuilder 和 StringBuffer 三者都是字符串处理类,但是它们之间存在着本质的区别。本文将从执行速度、线程安全性、字符串处理方式等方面对这三者进行比较和分析。 首先,从执行速度方面来...
在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的重要类,它们各自具有不同的特性和使用场景。下面将详细解析这三个类的区别。 首先,`String`类是最基础的字符串处理类,它被设计为不...
在Java编程语言中,`StringBuffer` 和 `StringBuilder` 是两个重要的类,它们主要用于处理可变的字符串。这两个类在很多方面都非常相似,但存在一些关键的区别。 **一、StringBuffer和StringBuilder的区别** 1. **...
在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的对象,但它们之间存在显著的区别。String是最常见的字符串类型,它的特点是不可变性。这意味着一旦一个String对象被创建,就不能进行...
string,stringBuffer,stringBuilder
Java中的`String`、`StringBuilder`和`StringBuffer`都是用来处理字符串的类,它们各自有不同的特性和适用场景。在理解它们之间的区别之前,我们首先要知道它们的共同点。 **共同点:** 1. **都是字符串类**:这三...