java源码阅读系列-String
来源:互联网 发布:java list 排序 编辑:程序博客网 时间:2024/05/16 05:23
String源码
惯例,膜拜Lee Boynton大神
先来看看官方注释对String的解释
* 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是常量,它们的值被创建后不能变化,String缓存区是可变的String,因为String类的不可变字符串对象是可以被共享的。
下面开始贴源码。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { ... }
没有继承其他的父类。
实现了Serializable接口,可以序列化。
实现了Comparable接口,主要是用来排序。
实现了CharSequence接口,这个就是一个字符序列,说明String就是字符数据组成的。
/** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0value是char的数组,可以知道String就是有char数组来存储的,看到没有,是final的,是不可变的。
hash变量,默认是0。
构造方法
1.无参的构造方法
public String() { this.value = "".value;}
2.有参的构造方法(参数为String类)
public String(String original) { this.value = original.value; this.hash = original.hash; }
3.有参的构造方法(用字符数组来构造)
第一种:
public String(char value[]) { this.value = Arrays.copyOf(value, value.length); }这里用了Arrays.coprOf方法.
第二种
public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= value.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); }offset表示开始位置,count表示截取的长度。
4.用整形的数组来构造
public String(int[] codePoints, int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= codePoints.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > codePoints.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } final int end = offset + count; // Pass 1: Compute precise size of char[] int n = count; for (int i = offset; i < end; i++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) continue; else if (Character.isValidCodePoint(c)) n++; else throw new IllegalArgumentException(Integer.toString(c)); } // Pass 2: Allocate and fill in char[] final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) v[j] = (char)c; else Character.toSurrogates(c, v, j++); } this.value = v; }
5.用字符数组构造
第一种
public String(byte bytes[], Charset charset) { this(bytes, 0, bytes.length, charset); }该构造方法制定用charset来解码制定的bytes[],为什么要使用charset来制定解码?因为在byte和String这种类型相互转换的时候,会出现乱码,所以我们要制定解码的格式.
第二种
public String(byte bytes[], int offset, int length, String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException("charsetName"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charsetName, bytes, offset, length); }这个是另一种解码方法,使用decode方法.
6.使用StringBuffer和StringBuilder来构造一个String
public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } }
public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); }
这两个方法很少用,因为我们有toString方法啊.
StringBuffer的toString方法
public synchronized String toString() { if (toStringCache == null) { toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); }StringBuilder的toString方法
public String toString() { // Create a copy, don't share the array return new String(value, 0, count); }
好了,构造方法就这么多.其实不是的,还有一些不建议使用的,就是你在使用的时候会有横线提示你不建议使用.这里就不贴出不来了.你需要知道这列就足够了.
其他方法
public int length() { return value.length; }
长度
public boolean isEmpty() { return value.length == 0; }是否为空
public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; }
public char[] toCharArray() { // Cannot use Arrays.copyOf because of class initialization order issues char result[] = new char[value.length]; System.arraycopy(value, 0, result, 0, value.length); return result; }转化为字符数组
public String trim() { int len = value.length; int st = 0; char[] val = value; /* avoid getfield opcode */ while ((st < len) && (val[st] <= ' ')) { st++; } while ((st < len) && (val[len - 1] <= ' ')) { len--; } return ((st > 0) || (len < value.length)) ? substring(st, len) : this; }
去掉两端空格
public String toUpperCase(Locale locale)//大写
public String toLowerCase(Locale locale)//小写
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; }
执行逻辑:先判断this == anObject,是就直接返回true;之后判断anObject是不是String类型的,不是直接返回false,是就继续往下比较,首先比较长度,然后在每一个去比较。
这次源码阅读就到这里。
阅读全文
0 0
- java源码阅读系列-String
- JAVA源码阅读--String
- java+String源码阅读1
- java String源码阅读2
- Java源码阅读之String
- Java源码阅读-String类
- java源码阅读系列-ArrayList
- java源码阅读系列-LinkedList
- java源码阅读-java.lang.String(01)
- java StringBuilder、stringbuffer、string 源码阅读笔记
- [Java]String类分析源码阅读
- java.lang.String源码阅读笔记
- 阅读Java String源码遇到的问题
- Java String类 源码注释阅读
- Java源码阅读之String(1)
- Java源码阅读之String(2)
- Java源码阅读之String(3)
- Java源码阅读之String(4)
- 利用GreenDao多线程断点续传
- java 文件输入输出流总结
- 请教java在jsp页面显示word文档问题
- IO流的前奏. Exception和File类
- 很多童鞋喜欢玩一些lol、dota这类游戏,这类游戏有一个特点,在你不死的情况下连续杀人会有不同称号。 下面输入一组字符,其中只包含K和D,K代表杀敌,D代表死亡,求他最高称号。 0/1/2
- java源码阅读系列-String
- makefile编译规则
- hadoop中分布式安装zookeeper
- 升级win10后 每次电脑休眠后再打开笔记本风扇狂转
- 惹毛程序员的十件事!需求变更居然不是排第一!
- Redis所有的命令
- 数数字 UVA1225
- 刷新
- 前端路由和后端路由