String Buffer 和 String Build学习笔记

public class Concatenation {
  public static void main(String[] args) {
    String mango = "mango";
    String s = "abc" + mango + "def" + 47;
    System.out.println(s);
  }
} /* Output:
abcmangodef47
*///:~

引入一段代码,大家都知道“+”与“+=”操作符是java中仅有的两个重载过的操作符(java并不允许程序员重载任何操作符),“+”可以用来连接String,如上述代码所示。

可能大家都知道这段代码是怎么工作的,按照编程思想书中的描述,可以用JDK自带的工具javap来反编译上述代码,命令如下:javap -c Concatenation 这里的“-c”表示将生成JVM代码。我跑了一下结果如下:

public class Concatenation {
  public Concatenation();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String mango
       2: astore_1
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<
init>":()V
      10: ldc           #5                  // String abc
      12: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: aload_1
      16: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: ldc           #7                  // String def
      21: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: bipush        47
      26: invokevirtual #8                  // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
      29: invokevirtual #9                  // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
      32: astore_2
      33: getstatic     #10                 // Field java/lang/System.out:Ljava/
io/PrintStream;
      36: aload_2
      37: invokevirtual #11                 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
      40: return
}

据说有汇编语言经验的看着会觉得眼熟,这里的重点就是编译器自动引入了java.lang.StringBuilder类,虽然源码并没有使用StringBuilder类,但是编译器自作主张地使用了它,因为它更高效。

StringBuilder是java SE5引入的,如果看源码会注意到这样一段注释

 * @author      Michael McCloskey
 * @see         java.lang.StringBuffer
 * @see         java.lang.String
 * @since       1.5
 */
public final class StringBuilder

since 1.5,那么在这之前java用的是什么呢,就是StringBuffer。

 * @author      Arthur van Hoff
 * @see     java.lang.StringBuilder
 * @see     java.lang.String
 * @since   JDK1.0
 */
 public final class StringBuffer

1.0就已经有了,而且是线程安全的,因此开销也会大些,所以在java SE5/6中(现在已经到8了),字符串的操作应该还会更快一些。

看过源码就会发现,注释的第一句话就对线程是否安全做了说明

/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang;

import java.util.Arrays;

/**
 * A thread-safe, mutable sequence of characters.
 * A string buffer is like a {@link String}, but can be modified. At any
 * point in time it contains some particular sequence of characters, but
 * the length and content of the sequence can be changed through certain
 * method calls.

看看源码就会发现,StringBuffer类的很多方法都是用了synchronized关键字声明,而StringBuilder并没有,StringBuilder属于非线程安全。

StringBuffer和StringBuilder的父类都是AbstractStringBuilder,他们的构造方法都是调用父类的构造方法

/**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }
  /**
     * Constructs a string builder with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuilder() {
        super(16);
    }
    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
时间: 2024-10-03 00:50:06

String Buffer 和 String Build学习笔记的相关文章

String Buffer和String Builder(String类深入理解)

String在Java里面JDK1.8后它属于一个特殊的类,在创建一个String基本对象的时候,String会向“ 字符串常量池(String constant pool)” 进行检索是否有该数据(字符串)存在,如果存在则向该数据进行实例引用,返回到创建的String对象.所以当创建两个不同名字,相同字符串的常量时,不可能会有两个不同的存储内存. String常量,在JDK1.8后便可以任意修改,不会创建新的内存地址对内存应用的浪费. (常量与常量比较) String de="你好婷婷&quo

String Buffer和String Builder的区别(转)

相信大家看到过很多比较String和StringBuffer区别的文章,也明白这两者的区别,然而自从Java 5.0发布以后,我们的比较列表上将多出一个对象了,这就是StringBuilder类.String类是不可变类,任何对String的改变都会引发新的String对象的生成:而StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象,可变和不可变类这一对对象已经齐全了,那么为什么还要引入新的StringBuilder类干吗?相信大家都有此疑问,我也如此.下面,我们

Lua学习笔记8:文件读写

lua中文件读写经常在游戏配置中用到,比如客户端的音效音乐开关等. Lua官方API文档:点这里 I/O库为文件操作提供4个主要函数:io.open(),io.read(),io.write和io.close(). io.open(文件路径,打开方式):以指定方式打开一个文件,打开成功返回一个文件句柄,失败返回nil和错误描述. 可以传入以下六种打开方式: "r":读模式(默认): "w":写模式: "a":附加模式: "r+"

Android-Universal-Image-Loader学习笔记(4)--download

该包所包含的图片如下 其中ImageDownloader为接口,BaseImageDownloader为ImageDownloaer的实现类. ImageDownloader(接口) 该接口对外提供了一个接口方法: InputStream getStream(String imageUri,Object extra) throws IOException; 很明显该方法的作用很明显是获取imageUri指定的图片文件的输入流. 由于imageUri所指定的文件源可以来自不同种类的服务器或者地址,

《Javascript权威指南》学习笔记之十一:处理字符串---String类和正则表达式

一.正则表达式的基本语法 1.概念:正则表达式由普通字符和特殊字符(元字符)组成的文本模式,该模式描述在查找字符串主体时待匹配的一个或者多个字符串.正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配. 普通字符包括所有的大小写字母字符.所有数字.所有标点符号及一些特殊符号.普通字符本身可以组成一个正则表达式,也可以和元字符组合组成一个正则表达式:而元字符则具有特殊的含义,包括().[].{}./.^.$.*.+.?...|.-.?:.?=.?! 2.基本语法 3.优先权含义 二.使用

非专业码农 JAVA学习笔记 6java工具类和算法-string

续<非专业码农 JAVA学习笔记 5 java工具类和算法> 五.字符串string 字符串和字符的差别:字符串双引号括起来”n”,字符用单引号括起来,表示一种符号’\n’ 1.string的主要方法和属性 类 方法或者属性 备注 定义string Stirng s=new string(“值”),string s=”值” 属性 string.length:string的长度为字节 方法startswith,endswith s.startwith(“值”)-以值为开头,s.endswith(

基于JDK1.8的String源码学习笔记

String,可能是学习Java一上来就学习的,经常用,但是却往往只是一知半解,甚至API有时也得现查.所以还是老规矩,倒腾源码. 一.java doc 这次首先关注String的doc,因为其实作为这么完备的语言,我感觉java 的doc是写的非常清楚的. /*Strings are constant; their values cannot be changed after they * are created. String buffers support mutable strings.

C++ Primer 学习笔记_27_操作符重载与转换(2)--++/--运算符重载、!运算符重载、赋值运算符重载 、String类([]、 +、 += 运算符重载)、&gt;&gt;和&lt;&lt;运算符重载

C++ Primer 学习笔记_27_操作符重载与转换(2)--++/--运算符重载.!运算符重载.赋值运算符重载 .String类([]. +. += 运算符重载).>>和<<运算符重载 一.++/--运算符重载 1.前置++运算符重载 成员函数的方式重载,原型为: 函数类型 & operator++(); 友元函数的方式重载,原型为: friend 函数类型 & operator++(类类型 &); 2.后置++运算符重载 成员函数的方式重载,原型为:

C++ Primer(第五版)学习笔记_5_标准模板库string(2)

C++ Primer(第五版)学习笔记_5_标准模板库string(2) 10.搜索string对象的元素或子串 采用find()方法可查找字符串中的第一个字符元素(char, 用单引号界定)或者子串(用双引号界定):如果查到,则返回下标值(从0开始计数),如果查不到,则返回一个很大的数string:npos(即:4294967295). #include <iostream> #include <stdio.h> #include <string> using nam