String源码j简单分析

分析:

1、

 private final char value[];

String内部由这个char数组维护String的字符。首先String类用final修饰,不可继承,其次,value[]用 fianl修饰,代表引用不可变。

    public String() {
        this.value = new char[0];
    }

当调用无参构造方法时,将char数组初始化为char[0]。

2、 String中的codePoint

codePoint  举例来说: “我”->对应的codePoint 为十进制的25105->十六进制的6211->UNICODE编码表中的6211(“我”字在UNICODE编码表中对应的16进制数)

3、

public byte[] getBytes(String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null) throw new NullPointerException();
        return StringCoding.encode(charsetName, value, 0, value.length);
    }

根据某编码格式编码

4、equals方法

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

5、测试两个字符串区域是否相等。

    public boolean regionMatches(int toffset, String other, int ooffset,
            int len) {
        char ta[] = value;
        int to = toffset;
        char pa[] = other.value;
        int po = ooffset;
        // Note: toffset, ooffset, or len might be near -1>>>1.
        if ((ooffset < 0) || (toffset < 0)
                || (toffset > (long)value.length - len)
                || (ooffset > (long)other.value.length - len)) {
            return false;
        }
        while (len-- > 0) {
            if (ta[to++] != pa[po++]) {
                return false;
            }
        }
        return true;
    }

6、hashcode

返回此字符串的哈希码。 String 对象的哈希码根据以下公式计算:

 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
 

使用 int 算法,这里 s[i] 是字符串的第 i 个字符, n 是字符串的长度, ^ 表示求幂。(空字符串的哈希值为 0。)

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

7、截取子串,返回的是new 的String

    public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
    }

8、字符串拼接,返回的时new String,所以不建议多次拼接,多次拼接请选StringBuffer

    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }

9、valueOf方法要注意,如果传进来的字符串为null,则会自动new String("null")返回,否则返回对象.toString()

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
时间: 2024-10-10 22:23:07

String源码j简单分析的相关文章

java线程池源码的简单分析

工作中用过线程池来进行多线程的操作,但是也仅仅是停留在使用方面,没有深入研究,现在通过源码来仔细研究下java的线程池.关于线程池的优缺点就不研究了,直接通过一个源码来看看java中线程池的原理. 使用ThreadPoolExecutor来创建一个线程池 public class MultipleThread { public static void main(String[] args) { /** * 通过ThreadPoolExecutor来创建一个线程池 * * 我们创建的线程池 核心线

n2n源码核心简单分析一

首先在开篇之前介绍下内网打洞原理 场景:一个服务器S1在公网上有一个IP,两个私网机器C1,C2 C1,C2分别由NAT1和NAT2连接到公网,我们需要借助S1将C1,C2建立直接的TCP连接,即由C1向C2打一个洞,让C2可以沿这个洞直接连接到C1主机,也就成了局域网访问的模式. 实现过程如下: S1启动两个网络监听(主连接监听,打洞监听) 由于S1是公网,所以C1,C2和S1保持通信, 当C1需要和C2建立直接的TCP连接时,首先连接S1的打洞监听端口,并发给S1请求协助连接C2的申请,同时

从源码上,分析AsyncTask的实现

Android开发者们应该都知道AsyncTask这个类,它是系统提供的一个异步任务类,可以方便的让我们实现异步操作.在本篇文章中,我将带大家进入源码,简单分析一下AsyncTask的实现. 首先,贴上AsyncTask类的源码: package android.os; import java.util.ArrayDeque; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; impo

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

String源码分析

String类内部维护了一个char[]类型的value用来存储字符串,相对来说源码较为简单些. 1.不可变性 String的不可变主要体现在三个方面: String类被定义为final类型,不可被继承 String中的value[]被定义为final String中的所有生成新的String的操作底层都调用Array.copy或者System.copy来生成一个新的String对象 2.构造函数,String的构造函数较为简单,但以下几个较为特殊 public String(String or

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

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

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

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

从Handler+Message+Looper源码带你分析Android系统的消息处理机制

引言 [转载请注明出处:从Handler+Message+Looper源码带你分析Android系统的消息处理机制 CSDN 废墟的树] 作为Android开发者,相信很多人都使用过Android的Handler类来处理异步任务.那么Handler类是怎么构成一个异步任务处理机制的呢?这篇 博客带你从源码分析Android的消息循环处理机制,便于深入的理解. 这里不得不从"一个Bug引发的思考"开始研究Android的消息循环处理机制.说来话长,在某一次的项目中,原本打算开启一个工作线