String源码简析(未完成,待本周末更新)

简介: String是Java中的常用类,本文对String源码做简要分析。

类和接口

String类被定义成public final class,所以String类无法被继承。

String类实现了Serializabel、Comparabe、CharSequence三个接口,分别对应着序列化、排序、字符串处理三个方面的功能。

类属性

String类底层有固定长度的字符数组组成,用hash的方法缓存字符串,含有一个序列化ID以及一个用于序列化的ObjectStreamField类,这个类我们会单独拿出一篇文章来讲。

private final char value[];
private int hash;
private static final long seriaVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];


类方法

构造方法

String构造数据的构造方法有很多实现方法。

默认构造方法

public String();

新建一个单个字符的char数组。常见于String str = new String();

带参构造方法

public String(String original);

String类型的传参直接赋值

public String(char value[]);

char数组则使用Arrays来直接拷贝,当然,可以在传参的时候,可以再加上位移量和长度(数量),详见String的源码

public String(int[] codePoint, int offset, int count);
public String(byte ascii[], int hibyte, int offset, int count);
public String(byte bytes[], Charset charset);
public String(byte bytes[], int offset, int length);
public String(byte bytes[]);

一些byte及编码类型的传参不再赘述。

public String(StringBuffer buffer);
public String(StringBuilder builder);

JDK1.5之后,String可以通过StringBuffer和StringBuilder调用Arrays.copyOf()来初始化String。其中,StringBuffer在调用的时候,会加锁以保证线程安全。

一般方法

字符操作length()isEmpty()charAt()codePointAt()codePointBefore()codePointCount()getBytes() 方法功能同名。

public boolean equals(Object anObject);
public boolean equalsIgnoreCase(String anotherString); // 大小写不敏感
  • String是final对象,所以在写equals方法时,是在比较String的各位char数值。
  • String是不可变对象,所以该方法没有涉及线程相关的设计。
public boolean contentEquals(StringBuffer sb);
public boolean contentEquals(CharSequence cs);
  • equals()方法只能比较String,而contentEquals的比较类型更多
  • contentEquals针对StringBuffer、StringBuilder、String、Charsequence有着不同的比较方法。
  • StringBuffer多加了一个synchronnized来保证线程安全。
  • contentEquals功能同名,只比较内容,而忽略类型。
public int compareTo(String anotherString);

按字典序列比较内容,返回不同字符处的距离或不同字符串长度,相等返回0

内部类 CaseInsensitiveComparator

我们发现内部类CaseInsensitiveComparator的compare比较方法为了实现大小写不敏感,把字符分别toUppperCasetoLowerCase比较了一遍,

一般方法

public boolean regionMatches(int toffset, String other, int ooffset,int len);
public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len);

比较两个字符串从某处开始的特定长度的字串是否相等。

public String concat(String str);

concact是拼接函数,其中为了设计char数组的拷贝,使用了传入String对象的getChars()方法。

void getChars(char dst[], int dstBegin) {
    System.arraycopy(value, 0, dst, dstBegin, value.length);
}

在这个函数中,使用了System的arraycopy方法,把当前字符串拷贝到传入字符串数组的结尾。

最后,concat返回一个新的String对象

public String replace(char oldChar, char newChar) {
    if (oldChar != newChar) {
        int len = value.length;
        int i = -1;
        char[] val = value; /* avoid getfield opcode */

        while (++i < len) {
            if (val[i] == oldChar) {
                break;
            }
        }
        if (i < len) {
            char buf[] = new char[len];
            for (int j = 0; j < i; j++) {
                buf[j] = val[j];
            }
            while (i < len) {
                char c = val[i];
                buf[i] = (c == oldChar) ? newChar : c;
                i++;
            }
            return new String(buf, true);
        }
    }
    return this;
}

replace方法用于返回一个替换字符串,但是这个方法重复执行了部分的循环操作。第一个循环用于找到第一个匹配的字符的位置,之后,再从头到此位置进行替换,最后从该位置之后再判断。这样做的目的是什么呢?

  • Java是高地址存低位,低地址存高
相关文章
|
6月前
|
存储 安全 编译器
Go语言源码剖析-String和unsafe包
Go语言源码剖析-String和unsafe包
44 0
|
9月前
|
存储 安全 Java
高频面试题-JDK集合源码篇(String,ArrayList)
都是List的子集合,LinkedList继承与Dqueue双端队列,看名字就能看出来前者是基于数组实现,底层采用Object[]存储元素,数组中的元素要求内存分配连续,可以使用索引进行访问,它的优势是随机访问快,但是由于要保证内存的连续性,如果删除了元素,或者从中间位置增加了元素,会设计到元素移位的操作,所以增删比较慢。
56 0
|
9月前
|
存储 消息中间件 缓存
从源码上聊聊Redis-String、List的结构实现
本文的数据类型只讲底层结构和部分机制,不讲具体的使用,使用的话自行bing,但是会提一些应用场景
138 1
从源码上聊聊Redis-String、List的结构实现
|
9月前
|
存储 安全 Java
【JavaSE】Java基础语法(三十七):Java 中的 String 类(源码级别)(2)
2.11 char[] toCharArray() 2.12 String substring(int beginIndex) 从传入的索引处截取,截取到末尾,得到新的字符串 2.13 String substring(int beginIndex, int endIndex) 根据开始和结束索引进行截取,得到新的字 符串(包含头,不包含尾)
|
9月前
|
存储 Java
【JavaSE】Java基础语法(三十七):Java 中的 String 类(源码级别)(1)
String 表示 字符串类型,属于 引用数据类型 。Java 中 String 是 不可变 的。 在 Java 当中 双引号 括起来的字符串,是直接存储在“方法区”的“字符串常量池”当中的。 1. 构造方法 1.1 String()
|
10月前
|
NoSQL 编译器 Serverless
Redis源码中字符串String的实现
Redis源码中字符串String的实现
36 0
|
11月前
|
存储 缓存 安全
Java - String源码解析及常见面试问题
Java - String源码解析及常见面试问题
72 0
|
存储 NoSQL Java
Redis源码剖析之SDS(Simple Dynamic String)
Redis源码剖析之SDS(Simple Dynamic String)
95 0
Redis源码剖析之SDS(Simple Dynamic String)
JDK源码系列(3)-String
JDK源码系列(3)-String
JDK源码系列(3)-String
|
存储 缓存 安全
细读源码之Java String (一)
细读源码之Java String (一)
68 0
细读源码之Java String (一)