JDK源码-String

1,字符串,String类。

-1,字符串是常量,他们的值在创建后不能更改。字符串缓冲区支持可变的字符串。

-2,String重载了Java中的+操作。

-3,String对象是不可变的,你可以给一个String对象加任意多的别名。因为String对象具有只读特性,所以指向他的任何引用都不能改变它的值。

2,String类的成员变量

-1,value 存储字符串的char数组。


 private final char value[];

-2,offset:存储使用的首元素index。


   /** The offset is the first index of the storage that is used. */

    private final int offset;

-3,count:String中存储的char数量。


  /** The count is the number of characters in the String. */

    private final int count;

-4,hash:字符串的hash值。


/** Cache the hash code for the string */

    private int hash; // Default to 0

-5,


/**

     * Class String is special cased within the Serialization Stream Protocol.

     *

     * A String instance is written initially into an ObjectOutputStream in the

     * following format:

     * <pre>

     *      <code>TC_STRING</code> (utf String)

     * </pre>

     * The String is written by method <code>DataOutput.writeUTF</code>.

     * A new handle is generated to  refer to all future references to the

     * string instance within the stream.

     */

    private static final ObjectStreamField[] serialPersistentFields =

        new ObjectStreamField[0];

3,构造方法。

-1,String():构造空的字符串对象。默认内部数组长度为0


 public String() {

	this.offset = 0;

	this.count = 0;

	this.value = new char[0];

    }

-2,String(String):使用指定字符串构造String,创建对应字符串的副本,因为字符串是不可变的,所以没必要使用此构造方法。


  public String(String original) {

	int size = original.count;

	char[] originalValue = original.value;

	char[] v;

  	if (originalValue.length > size) {

 	    // The array representing the String is bigger than the new

 	    // String itself.  Perhaps this constructor is being called

 	    // in order to trim the baggage, so make a copy of the array.

            int off = original.offset;

            v = Arrays.copyOfRange(originalValue, off, off+size);

 	} else {

 	    // The array representing the String is the same

 	    // size as the String, so no point in making a copy.

	    v = originalValue;

 	}

	this.offset = 0;

	this.count = size;

	this.value = v;

    }

-3,String(char[] ):使用char数组构建String


    public String(char value[]) {

	int size = value.length;

	this.offset = 0;

	this.count = size;

	this.value = Arrays.copyOf(value, size);

    }

4,方法:

-1,length():返回字符串中字符数。


   public int length() {

        return count;

    }

-2,isEmpty():判断字符串是否为空。


  public boolean isEmpty() {

	return count == 0;

    }

-3,charAt(int):获取对应索引的字符。


   public char charAt(int index) {

        if ((index < 0) || (index >= count)) {

            throw new StringIndexOutOfBoundsException(index);

        }

        return value[index + offset];

    }

-4,equalsIgnoreCase(String):忽略大小写比较两字符串差异。


   public boolean equalsIgnoreCase(String anotherString) {

        return (this == anotherString) ? true :

               (anotherString != null) && (anotherString.count == count) &&

	       regionMatches(true, 0, anotherString, 0, count);//调用此方法

    }

判断;两字符串中从开始位置到固定长度的字符是否相等。


public boolean regionMatches(boolean ignoreCase, int toffset,

                           String other, int ooffset, int len) {

        char ta[] = value;

        int to = offset + toffset;

        char pa[] = other.value;

        int po = other.offset + ooffset;

        // Note: toffset, ooffset, or len might be near -1>>>1.

        if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len) ||

                (ooffset > (long)other.count - len)) {

            return false;

        }

        while (len-- > 0) {

            char c1 = ta[to++];

            char c2 = pa[po++];

            if (c1 == c2) {

                continue;

            }

            if (ignoreCase) {

                // If characters don‘t match but case may be ignored,

                // try converting both characters to uppercase.

                // If the results match, then the comparison scan should

                // continue.

                char u1 = Character.toUpperCase(c1);

                char u2 = Character.toUpperCase(c2);

                if (u1 == u2) {

                    continue;

                }

                // Unfortunately, conversion to uppercase does not work properly

                // for the Georgian alphabet, which has strange rules about case

                // conversion.  So we need to make one last check before

                // exiting.

                if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {

                    continue;

                }

            }

            return false;

        }

        return true;

    }

-5,startWith(String, int):判断字符串是不是从某索引位置以某字符串开始。


    public boolean startsWith(String prefix, int toffset) {

	char ta[] = value;

	int to = offset + toffset;//索引开始位置

	char pa[] = prefix.value;

	int po = prefix.offset;//开始位置

	int pc = prefix.count;//总长度

	// Note: toffset might be near -1>>>1.

	if ((toffset < 0) || (toffset > count - pc)) {

	    return false;

	}

	while (--pc >= 0) {

	    if (ta[to++] != pa[po++]) {

	        return false;

	    }

	}

	return true;

    }

-6,endWith(String):以某字符串结束。


  public boolean endsWith(String suffix) {

	return startsWith(suffix, count - suffix.count);//获取开始比较位置,然后调用开始比较的方法,开始比较。

    }

-7,startWith(String):判断字符串是否以某字符串开始。


  public boolean startsWith(String prefix) {

	return startsWith(prefix, 0);

    }
时间: 2024-10-18 05:49:00

JDK源码-String的相关文章

JDK源码之String、StringBuffer、StringBuilder

就String而言,平时工作中用得最多,但是很多时候还是用不好,有必要对他进行整体的分析下.如果看过Thinking in java,再看下JDK的源码,很多东西就会变得十分明了.现在对String的底层实现进行下分析. 首先是对构造函数而言,我工作中最常用到的可能就是new String(str)这个构造函数了,所以再在此关注这一个.这个构造函数是对传进来的String进行解析,将其放进一个数组当中,我们设定为arrayOfChar,String类定义了全局变量offset(偏移量),coun

JDK源码学习--String篇(二) 关于String采用final修饰的思考

JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JDK源码的时候,有粗略的思考过,今天下班后又把<Thinking in Java>中关于final的内容重新看了一遍,对此写下一些关于自己的理解和想法. String类中final关键字的使用 final关键字,用来描述一块数据不能被改变,两种可能理由:设计.效率 final使用的三种情况:数据.方

JDK源码分析之String篇

------------------------------String在内存中的存储情况(一下内容摘自参考资料1)----------------------------------- 前提:先了解下什么是声明,什么时候才算是产生了对象实例 其中x并未看到内存分配,变量在使用前必须先声明,再赋值,然后才可以使用.java基础数据类型会用对应的默认值进行初始化 一.首先看看Java虚拟机JVM的内存块及其变量.对象内存空间是怎么存储分配的 1.栈:存放基本数据类型及对象变量的引用,对象本身不存放

jdk 源码阅读有感(一)String

闲暇之余阅读 jdk 源码. (一)核心属性 /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 String的核心结构,char型数组与 int 型 hash值. (二)构造器 构造器方面,由于上述两个值是不可更改的,所以直接 对 String

JDK 源码 阅读 - 2 - 设计模式 - 创建型模式

A.创建型模式 抽象工厂(Abstract Factory) javax.xml.parsers.DocumentBuilderFactory DocumentBuilderFactory通过FactoryFinder实例化具体的Factory. 使用例子: DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilder

JDK源码分析之concurrent包(三) -- Future方式的实现

上一篇我们基于JDK的源码对线程池ThreadPoolExecutor的实现做了分析,本篇来对Executor框架中另一种典型用法Future方式做源码解读.我们知道Future方式实现了带有返回值的程序的异步调用,关于异步调用的场景大家可以自行脑补Ajax的应用(获取返回结果的方式不同,Future是主动询问获取,Ajax是回调函数),这里不做过多说明. 在进入源码前,首先来看下Future方式相关的API: 接口Callable:有返回结果并且可能抛出异常的任务: 接口Future:表示异步

JDK源码学习系列08----HashMap

                                                          JDK源码学习系列08----HashMap 1.HashMap简介 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,

JDK源码学习LinkedList

LinkedList是List接口的子类,它底层数据结构是双向循环链表.LinkedList还实现了Deque接口(double-end-queue双端队列,线性collection,支持在两端插入和移除元素).所以LinkedList既可以被当作双向链表,还可以当做栈.队列或双端队列进行操作.文章目录如下: 1.LinkedList的存储实现(jdk 1.7.0_51) 2.LinkedList的读取实现 3.LinkedList的性能分析 下面我们进入正题,开始学习LinkedList. L

JDK源码学习系列06----Vector

                                            JDK源码学习系列06----Vector 1.Vector简介 Vector的内部是数组实现的,它和ArrayList非常相似,最大的不同就是 Vector 是线程安全(同步)的. public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.S