String源码(1.8)

1.String  存储的值就是一个char数组

1 /** The value is used for character storage. */ 2 private final char value[];

2.传入int作为参数,这个int是这个字对应的Unicode(16进制数)。每个最大65535 0xFFFF

public static final int MIN_CODE_POINT = 0x000000;

public static final int MAX_CODE_POINT = 0X10FFFF;

UTF-16中的基本单位是两个字节的码元,基本的码元范围是(0x0000-0xFFFF), UTF-16的字符映射范围是(U+0000,U+10FFFF),

当一个生僻字符需要使用0xFFFF以上的映射范围时,其需要使用两个码元(4Byte)进行表示. 其映射规则如下

第一个码元(前导代理)范围:0xD800 - 0xDBFF

第二个码元(后尾代理)范围:0xDC00 - 0xDFFF

有:(0xDBFF-0xD800+1)*(0xDFFF-0xDC00+1) === (0x10FFFF-0xFFFF)双射

所以(0xD800 - 0xDBFF)范围内的码元不能单独表示字符,其必须与后尾代理一起构成一个完整字符.

参考:https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

 1     public String(int[] codePoints, int offset, int count) {
 2         if (offset < 0) {
 3             throw new StringIndexOutOfBoundsException(offset);
 4         }
 5         if (count <= 0) {
 6             if (count < 0) {
 7                 throw new StringIndexOutOfBoundsException(count);
 8             }
 9             if (offset <= codePoints.length) {
10                 this.value = "".value;
11                 return;
12             }
13         }
14         // Note: offset or count might be near -1>>>1.
15         if (offset > codePoints.length - count) {
16             throw new StringIndexOutOfBoundsException(offset + count);
17         }
18
19         final int end = offset + count;
20
21         // Pass 1: Compute precise size of char[]
22         int n = count;
23         for (int i = offset; i < end; i++) {
24             int c = codePoints[i];
25             if (Character.isBmpCodePoint(c))
26                 continue;
27             else if (Character.isValidCodePoint(c))
28                 n++;
29             else throw new IllegalArgumentException(Integer.toString(c));
30         }
31
32         // Pass 2: Allocate and fill in char[]
33         final char[] v = new char[n];
34
35         for (int i = offset, j = 0; i < end; i++, j++) {
36             int c = codePoints[i];
37             if (Character.isBmpCodePoint(c))
38                 v[j] = (char)c;
39             else
40                 Character.toSurrogates(c, v, j++);
41         }
42
43         this.value = v;
44     }
Character.isBmpCodePoint(c) 判断是不是只有一个码元的字符,Character.isValidCodePoint(c) 判断在字符范围内。此时n++,这个int要用2个char表示。
Character.toSurrogates(c, v, j++) 将int分解成2个char

3.length()返回的是码元char的数量,而不是字的数量,有些字要占两个char

1     public int length() {
2         return value.length;
3     }

4.String.join  免去StringBuild自己拼还要去掉最后一个delimiter

1 public static String join(CharSequence delimiter, CharSequence... elements)

5.native 关键字 调用别的语言的代码。

1 public native String intern();

深入解析String#intern

https://tech.meituan.com/in_depth_understanding_string_intern.html


 
时间: 2024-11-02 20:53:29

String源码(1.8)的相关文章

java学习笔记-String源码分析(2)

承接上篇文章关于String源码的分析,我们继续总结String中的方法 方法汇总 4.subString方法 public String substring(int beginIndex) public String substring(int beginIndex, int endIndex) subString()有2个重载版本,beginIndex指定开始索引(包括),endIndex指定结束索引(不包括).两个方法实现类似,我们关注一个即可. public String substri

基于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.

String源码中的&quot;avoid getfield opcode&quot;

引言: 之前一篇文章梳理了String的不变性原则,还提到了一段源码中注释"avoid getfield opcode",当时通过查阅资料发现,这是为了防止 getfield(获取指定类的实例域,并将其值压入到栈顶)这个操作码的执行,这篇文章想从字节码的角度去分析一下. 先看一段代码吧 /** * Created by chenqimiao on 16/11/29. */ public class Main { public char[] chars = new char[10]; p

std::string源码探秘和性能分析

std::string源码探秘和性能分析 本文主要讲c++标准库的string的内部实现,以及对象拷贝的性能分析. 文中采用的源码版本为gcc-4.9,测试环境为centos7, x86_64,涉及到指针等数据类型的大小也假定是在64环境位下. stl源码可以在gnu gcc的官方网站下载到:https://gcc.gnu.org/ 头文件 vector头文件,该文件也可以直接在安装了g++的linux系统中找到.主要包含以下头内容: // vector #include <bits/strin

Java源码解析|String源码与常用方法

String源码与常用方法 1.栗子 代码: public class JavaStringClass { public static void main(String[] args) { String s ="hello"; s = "world"; //内存地址已经修改 原来地址上的值还是不变的 String s2 = "hello"; //从常量值中找到并引用 String s4 = new String("hello"

String源码解析

定义 先看一下文档中的注释 12345 * Strings are constant; their values cannot be changed after they * are created. String buffers support mutable strings. * Because String objects are immutable they can be shared. */ String对象是常量,创建之后就不能被修改,所以该对象可以被多线程共享. 123456789

死磕 Java 系列(一)&mdash;&mdash; 常用类(1) String 源码解析

写在前面 这是博主新开的一个 java 学习系列,听名字就可以看出来,在这一些系列中,我们学习的知识点不再是蜻蜓点水,而是深入底层,深入源码.由此,学习过程中我们要带着一股钻劲儿,对我们不懂的知识充满质疑,力求把我们学过的知识点都搞清楚,想明白. 一.引言 在 java 的世界里,存在一种特殊的类,它们的创建方式极为特别,不需要用到 new XXX(当然也可以用这种方式创建), 但是却大量出现在我们的代码中,那就是 String 类.作为日常中使用频率最高的类,它是那么普通,普通到我们从来都不会

String源码解析(一)

本篇文章内的方法介绍,在方法的上面的注释讲解的很清楚,这里只阐述一些要点. Java中的String类的定义如下: 1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { ...} 可以看到,String是final的,而且继承了Serializable.Comparable和CharSequence接口. 正是因为这个特性,字符串对象可以被共享,例如下面

Java String 源码浅析

引言 从一段代码说起: public void stringTest(){     String a = "a"+"b"+1;     String b = "ab1";     System.out.println(a == b); } 大家猜一猜结果如何?如果你的结论是true.好吧,再来一段代码: public void stringTest(){     String a = new String("ab1");   

Java String源码解析

String类概要 所有的字符串字面量都属于String类,String对象创建后不可改变,因此可以缓存共享,StringBuilder,StringBuffer是可变的实现 String类提供了操作字符序列中单个字符的方法,比如有比较字符串,搜索字符串等 Java语言提供了对字符串连接运算符的特别支持(+),该符号也可用于将其他类型转换成字符串. 字符串的连接实际上是通过StringBuffer或者StringBuilder的append()方法来实现的 一般情况下,传递一个空参数在这类构造函