申明:转载请注明出处,如有商用目的请务必知会本人,感谢。

上一篇文章:http://blog.csdn.net/ts1122/article/details/8738336,介绍了String一些易错内容。这里接着大体介绍下String类提供的API。大体就是不对API做一一介绍,只是根据类型说个大概,再选择一些经典的方法详细说明下。说明下,这两篇文章都是基于JDK1.7.0_17版本进行说明的,本文章后面的内容会说到JDK1.7版本String类的实现和JDK1.6版本还是很大不同的。
        先说构造方法,String类里面构造方法很多。由于方法签名只与方法名称以及参数类型有关系,这么多构造方法的差异就只能是传递的参数类型和数目。不过有的构造方法基本不会被用到,比如下面两个:

  1. public String() {
  2. this.value = new char[0];
  3. }
  4. public String(String original) {
  5. this.value = original.value;
  6. this.hash = original.hash;
  7. }

第一个构造方法之所以不用,说明文档里面写的很清楚:由于String是不可变的,当前方法的基本没用。这个方法给出了一个指向空字符串的引用,之后指向的内容又不能改变,所以没有什么用处。Java里面有些类叫做不可变类,其定义为:类中的每个方法都不能改变其对象。一般这种类中的数据域都有加final修饰,String类就是一个不可变类,其数据域就加了final字符修饰。上面的第二个方法之所以不用是因为会多分配一块内存,JVM会在当前线程的stringpool中分配一块内存,之后在堆中再分配一块内存。构造一个String,我们一般只要用String = “abc”这种方式就足够了,而且简单高效,这种用法也是java推荐的。:-D
        下面是一组和String类数据域有关的方法:

  1. public int length()
  2. public boolean isEmpty()
  3. public char charAt(int index)
  4. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

这三个方法都是基于String的数据域char value[]实现的,比如返回value.length。这些方法经常有用到,得记住。最后一个方法是将String中数据域内容拷贝到char数组方法,用System.arraycopy的本地方法实现,效率应该很高。
        接下来是一组String内容比较方法:

  1. public boolean equals(Object anObject)
  2. public boolean equalsIgnoreCase(String anotherString)
  3. public boolean contentEquals(CharSequence cs)
  4. public int compareTo(String anotherString)

第一个方法比较两个字符串对象内容是否完全相等,如果是就返回true。第二个方法从方法名称就可以理解,不考虑大小写进行比较。看了下第二个方法的内部实现,先把字符统一转成大写进行比较,如果不行再转成小写进行比较,看说明文档对于Georgian alphabet就有这种大写不成要用小写的特殊情况。:-(   第三个方法和前面两个方法基本一样,只不过参数类型不同。最后一个方法和C语言中的一样:取两个字符串较短的长度,从第一个字符开始对两个字符串进行比较,如果出现第一个不同的字符则返回两个字符之间的差值。结果返回是0的话就说明两个字符串内容相等。但是这个方法在java中很少用到。
        一组新的字符串内容比较方法:

  1. public int indexOf(int ch)
  2. public int indexOf(int ch, int fromIndex)
  3. public int lastIndexOf(int ch)
  4. public boolean startsWith(String prefix)
  5. public boolean startsWith(String prefix, int toffset)
  6. public boolean endsWith(String suffix)
  7. public int indexOf(String str)
  8. public int indexOf(String str, int fromIndex)
  9. public int lastIndexOf(String str)

前面三个方法都是返回一个字符在当前字符串中的位置。后面一组方法是寻找一组字符串在当前字符串中的位置,和前面一组方法很相似。
        一组易被忽视会产生新的字符串对象的方法:

  1. public String substring(int beginIndex)
  2. public String substring(int beginIndex, int endIndex)
  3. public String replace(char oldChar, char newChar)
  4. public String toLowerCase()
  5. public String toUpperCase()
  6. public String trim()

这些都是对当前字符串内容进行截取,替换,大小写变更等操作的方法。由于String类是不可变类,这些方法不能改变对象内容,只能新分配内存保存操作结果,如果滥用这些方法会造成内存泄露的。
        这里根据public String substring(int beginIndex)说一下JDK1.6和JDK1.7String类的一些不同。JDK1.6上String类的数据域如下:

  1. /** The value is used for character storage. */
  2. private final char value[];
  3. /** The offset is the first index of the storage that is used. */
  4. private final int offset;
  5. /** The count is the number of characters in the String. */
  6. private final int count;

即其包含一个类似高中几何上向量的东西,给出内容同时还给出了一个起始点和长度的游标。JDK1.6中在实现substring最终会用到下面的方法:

  1. // Package private constructor which shares value array for speed.
  2. String(int offset, int count, char value[]) {
  3. this.value = value;
  4. this.offset = offset;
  5. this.count = count;
  6. }

这就是说截取一段某一个字符串中的一段,实际上并没有分配新的内存,只是提供了一个新的向量,返回的引用仍然指向原来的字符串。如果原来的字符串不再使用,仅使用新的截取的字符串,个人认为就造成内存浪费。如果每次都是从一个很长很长字符串中截取一小段内容,就造成了内存的极大浪费,这也是JDK1.6使用过程中,关于字符串的一个优化点。再看JDK1.7中String类就只有char value[]一个数据域,方法substring就采取了新的做法,如下:

  1. this.value = Arrays.copyOfRange(value, offset, offset+count);

这句代码完成这个方法实现主体,分配了新的内存,将需要的内容拷贝到新的内存中。看JDK文档中说明,1.6的这种做法是为了速度。:-D
       接下来就是valueOf方法,都是像    public static String valueOf(Object obj) 这样的类方法,这些方法的实现其实就是参数本身的toString方法的实现。最后就是split方法,这个涉及到了正则表达式,这里暂不介绍。:-D

版权声明:本文为博主原创文章,未经博主允许不得转载。

java 基于JDK中的源码总结下String二的更多相关文章

  1. Java基础-集合框架-ArrayList源码分析

    一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...

  2. Java并发工具类CountDownLatch源码中的例子

    Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...

  3. JDK源码阅读-------自学笔记(一)(java.lang.Object重写toString源码)

    一.前景提要 Object类中定义有public String toString()方法,其返回值是 String 类型. 二.默认返回组成 类名+@+16进制的hashcode,当使用打印方法打印的 ...

  4. Java并发系列[5]----ReentrantLock源码分析

    在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...

  5. 观察者模式—jdk自带源码分析

    一:观察者模式简介 二:jdk实现观察者模式的源码 三:实际例子 四:观察者模式的优点和不足 五:总结 一:观察者模式简介 有时又被称为发布(publish )-订阅(Subscribe)模式.模型- ...

  6. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  7. JDK容器类Map源码解读

    java.util.Map接口是JDK1.2开始提供的一个基于键值对的散列表接口,其设计的初衷是为了替换JDK1.0中的java.util.Dictionary抽象类.Dictionary是JDK最初 ...

  8. 基于Eclipse搭建Hadoop源码环境

    Hadoop使用ant+ivy组织工程,无法直接导入Eclipse中.本文将介绍如何基于Eclipse搭建Hadoop源码环境. 准备工作 本文使用的操作系统为CentOS.需要的软件版本:hadoo ...

  9. Java集合系列[4]----LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHas ...

随机推荐

  1. Linux UDEV和为MySQL InnoDB共享表空间配置裸设备

    ⑴ UDEV 基础         udev 可管理保存在/dev 目录下的文件.文件只有在接入相应设备后才会生成.设备被拔出后自动删除     它还允许用户添加规则.以便修改/dev中默认的名称和权 ...

  2. mysql中怎样查看和删除唯一索引

    mysql中怎样查看和删除唯一索引. 查看唯一索引: show index from mytable;//mytable 是表名 查询结果例如以下: 查询到唯一索引后,怎样删除唯一索引呢,使用例如以下 ...

  3. android面试题之一

    在接下来的一段时间,我将收集一些常见面试题,综合网上资料加自己测试与理解,将其总结出来和大家分享,里面难免有一些问题,希望大家提出宝贵意见以便及时更正. 一.Activity.Service.Broa ...

  4. BZOJ 1412: [ZJOI2009]狼和羊的故事( 最小割 )

    显然是最小割...把狼的领地连S, 羊的领地连T, 然后中间再连边, 跑最大流就OK了 -------------------------------------------------------- ...

  5. Python 模块(五)

    目录 模块介绍 time &datetime模块 random json & picle 一.模块介绍 在我们日常的程序开发过程中,随着代码越写越多,在单个文件里的代码就会越来越长,越 ...

  6. C语言循环剖析(转载)

    一.if.else float变量与“零值”进行比较: float fTestVal = 0.0; if((fTestVal >= -EPSINON) && (fTestVal ...

  7. DFS 练习 (这篇真的是随笔)

    目的: 输入: 3 输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 代码如下: #include<stdio.h> ],b[],n; void dfs(in ...

  8. 带符号的char类型取值范围为什么是-128——127

    以前经常看到带符号的char类型取值范围是-128——127,今天突然想为什么不是-127——127,-128是怎么来的? 127好理解,char类型是8位,最高位是符号位,0正1负,所以011111 ...

  9. oschina iOS代码库

    iOS代码库 34Activity 54下拉刷新(pull-to-refresh) 143菜单 (Menu) 20位置信息(GPS/Location) 24iOS 表单 74提醒 (Notificat ...

  10. (step7.2.3)hdu 2554(N对数的排列问题——简单数论)

    题目大意:输入一个整数n,表示有n对整数.判断能否出现一种情况就是2个1之间有1个数,2个2之间有2个数..... 解题思路: 准备知识: ①n对数,共2*n个数.所以要有2*n个位置来放置这2*n个 ...