String 详解
String
String对象不可变,当对象创建完毕之后,如果内容改变则会创建一个新的String对象,返回到原地址中。
不可变优点:
多线程安全。
节省空间,提高效率。
源码:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
private final byte[] value;
private final byte coder;
private int hash; // Default to 0
public String(String original) {
this.value = original.value;
this.coder = original.coder;
this.hash = original.hash;
}
//new String()都是在堆上创建字符串对象。当调用 intern() 方法时,编译器会将字符串添加到字符串常量池中,并返回指向该常量的引用。
public native String intern();
}
第一种:直接赋一个字面量
String str1 = "ABCD";
最多创建一个String对象(先在字符串常量池先创建"ABCD"内存空间,再引用)
最少不创建String对象( 如果字符串常量池中存在"ABCD",那么str1直接引用。)
第二种:通过构造器创建
String str2 = new String("ABCD");
new 创建字符串时,首先查看池中是否有相同的字符串,如果有则拷贝一份放到堆中,然后返回堆中的地址。
如果池中没有则在堆中创建一分,然后返回堆中的地址。
常量字符串和变量拼接时(String str = baseStr + "01";),会调用StringBuilder.append()在堆上创建新的对象:
String s1 = "abc";
String s2 = "a";
String s3 = "bc";
String s4 = s2 + s3;
System.out.println(s1 == s4);
A:false,因为s2+s3实际上是使用StringBuilder.append()来完成,会生成不同的对象。
JVM确实对形如 String str = "java"; 的对象放在常量池中,但是它是在编译时做的。
而 String s = s2 + s3; 是在运行时候才能知道的,也就是说 s2 + s3 是在堆里创建的。
String s1 = "abc";
final String s2 = "a";
final String s3 = "bc";
String s4 = s2 + s3;
System.out.println(s1 == s4);
A:true,因为final变量在编译后会直接替换成对应的值,所以实际上等于s4="a"+"bc",而这种情况下,编译器会直接合并为s4="abc",所以最终s1==s4。
StringBuffer(可变字符串)
StringBuffer 与 StringBuilder 中的方法和功能完全是等价的。
线程安全(该对象方法中所有的方法都是用了synchronized修饰符),因此开销也会大。
StringBuilder(可变字符串)
StringBuffer 始于 JDK 1.0
StringBuilder 始于 JDK 1.5
从 JDK 1.5 开始,带有字符串变量的连接操作"+",JVM 内部采用的是 StringBuilder 来实现的,而之前这个操作是采用 StringBuffer 实现的。
StringBuilder是为了提高java中字符串连接的效率:
JVM内部采用了StringBuilder来连接字符串(即"+"操作),但是每次有执行"+"操作的语句时,
JVM都要new一个StringBuilder对象来处理字符串的连接,这在涉及很多的字符串连接操作时开销会很大。
所有我们自己使用StringBuilder来处理字符串的连接,可以提高java中字符串连接的效率
底层原理:
AbstractStringBuilder中采用一个byte[]来保存需要append的字符串,
byte[]有一个初始大小,当append的字符串长度超过当前byte[]容量时,则对byte[]进行动态扩展,
也即重新申请一段更大的内存空间,然后将当前byte[]拷贝到新的位置,
因为重新分配内存并拷贝的开销比较大,所以每次重新申请内存空间都是采用申请大于当前需要的内存空间的方式,这里是2倍
StringBuilder是JDK1.5发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。
常量池详解
https://www.cnblogs.com/loveer/p/11519739.html
String 详解的更多相关文章
- Java的String详解
Java的String详解 博客分类: Java javaStringString详解常用方法 Java的String类在开发时经常都会被使用到,由此可见String的重要性.经过这次认真仔细的学习 ...
- Python操作redis字符串(String)详解 (三)
# -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1.SET 命令用于设置 ...
- [读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析
前言 上次在公司开会时有同事分享windebug的知识, 拿的是string字符串Concat拼接 然后用while(true){}死循环的Demo来讲解.其中有提及string操作大量字符串效率低下 ...
- String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1)
本章主要介绍String和CharSequence的区别,以及它们的API详细使用方法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/string01. ...
- Java堆、栈和常量池以及相关String详解
一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
- String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别
本章主要介绍String和CharSequence的区别,以及它们的API详细使用方法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/string01. ...
- java String 详解
1.java语言的字符串序列是通过字符串类实现的.java提供了3个字符串类:String类.StringBuilder类和StringBuffer类.String类是不变字符串,StringBuff ...
- String详解
在开发中,我们都会频繁的使用String类,掌握String的实现和常用方法是必不可少的,当然,我们还需要了解它的内部实现. 一. String的实现 在Java中,采用了一个char数组实现Stri ...
- C#String详解
字符串:stringLength - 字符串的长度. TrimStart() 压缩空格即消除字符串开始空格TrimEnd() 消除结尾空格Trim() 同时消除开头和结尾空格.注:中间空格不消除,因为 ...
随机推荐
- ArrayList底层代码解析笔记
通过底层代码可以学习到很多东西: public class ArrayList<E> extends AbstractList<E> implements List<E& ...
- C语言指针变量的长度
#include <stdio.h> int main() { /********************************************* * * 指针的长度:不同机器可 ...
- webpack4.x的使用历程
第一次接触的webpack是在一个3.x的资料中 在4.x的运用中遇到了好多的坑,我就以小白的身份把我使用webpaxk的过程分享出来,其中很多不足欢迎大佬们指正 node安装不再赘述 一.安装 np ...
- 标准 IO 测试 标准输出,输入,出错缓冲大小;全缓冲文本流大小
例子:测试缓冲区大小 #include <stdio.h> int main(int argc, const char *argv[]) { //标准输入大小,没有输入内容时,标准输入缓冲 ...
- 50. Set接口和Set的实现类HashSet
集合分类:-------------------| Collection 单列集合的根接口 ---------------| List 如果实现了List接口的集合类,具备的特点是:有序,可重复- ...
- Delphi 日期函数(Day、Mon、Year、Week)使用方法描述
Day 开头的函数 ● function DateOf(const Avalue: TDateTime): TDateTime; 描述 使用 DateOf 函数用来把一个 TDateTime 类型的变 ...
- 暴力模拟——cf988E
很简单的题,就是模拟一下 #include<bits/stdc++.h> using namespace std; #define ll long long ll n,a[],len; i ...
- POJ3436:ACM Computer Factory-最大流
目录 目录 思路: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 目录 题意:传送门 原题目描述在最下面. 题目真难读懂 有\(n\)台机器,每台机器有\(p\)个部分,每台机 ...
- Vue.js - 路由 vue-router 的使用详解2(参数传递)
一.使用冒号(:)的形式传递参数 1,路由列表的参数设置 (1)路由列表的 path 是可以带参数的,我们在路由配置文件(router/index.js)里以冒号的形式设置参数. (2)下面样例代码中 ...
- arcgis api for javascipt 输出图片
地图模板制作-发布-gpurl调用 window.open可以直接打开url链接. saveas可以另存,仅支持ie浏览器 <!DOCTYPE html><html><h ...