- 浏览: 79257 次
文章分类
最新评论
从零开始读JAVA源码01-java.lang.String
工作很久了,一直在讲面向对象开发,API随查随用,发现JAVA源码细节都没怎么读过,理解过。最近看了一部分,阿里公司的一些试题,发现有些概念还是很模糊的,准备搞一个从零开学读源码系列,深刻的理解下JDK API的类树结构,先把整个学习逻辑理一下,一共要学的源码包,包含:java.lang、java.util、java.io、java.net、java.applet、java.awt、java.swing。后三个包不作为重点看,学习的原则是,弄透彻,一点带面的去读,写的东西都是非常基础的东西,各位大牛可以直接跳过此文,从中发现JAVA代码效率优化和内存优化的点和启发,希望能坚持下来,先在此立一个flag,哈哈。
附图(转载网上的一张图):
今天首先开始学的是 java.lang包的String类,以下来自jdk1.6API
所有已实现的接口:
Serializable, CharSequence, Comparable<String>
public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence
String 类
String() 初始化一个新创建的 String 对象,使其表示一个空字符序列。 |
String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String 。 |
String(byte[] bytes, Charset charset) 通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String 。 |
String(byte[] ascii, int hibyte) 已过时。 该方法无法将字节正确地转换为字符。从 JDK 1.1 开始,完成该转换的首选方法是使用带有 Charset 、字符集名称,或使用平台默认字符集的 String 构造方法。 |
String(byte[] bytes, int offset, int length) 通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String 。 |
String(byte[] bytes, int offset, int length, Charset charset) 通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String 。 |
String(byte[] ascii, int hibyte, int offset, int count) 已过时。 该方法无法将字节正确地转换为字符。从 JDK 1.1 开始,完成该转换的首选方法是使用带有 Charset 、字符集名称,或使用平台默认字符集的 String 构造方法。 |
String(byte[] bytes, int offset, int length, String charsetName) 通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String 。 |
String(byte[] bytes, String charsetName) 通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String 。 |
String(char[] value) 分配一个新的 String ,使其表示字符数组参数中当前包含的字符序列。 |
String(char[] value, int offset, int count) 分配一个新的 String ,它包含取自字符数组参数一个子数组的字符。 |
String(int[] codePoints, int offset, int count) 分配一个新的 String ,它包含 Unicode 代码点数组参数一个子数组的字符。 |
String(String original) 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。 |
String(StringBuffer buffer) 分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。 |
String(StringBuilder builder) 分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。 |
char |
charAt(int index) 返回指定索引处的 char 值。 |
int |
codePointAt(int index) 返回指定索引处的字符(Unicode 代码点)。 |
int |
codePointBefore(int index) 返回指定索引之前的字符(Unicode 代码点)。 |
int |
codePointCount(int beginIndex, int endIndex) 返回此 String 的指定文本范围中的 Unicode 代码点数。 |
int |
compareTo(String anotherString) 按字典顺序比较两个字符串。 |
int |
compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。 |
String |
concat(String str) 将指定字符串连接到此字符串的结尾。 |
boolean |
contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true。 |
boolean |
contentEquals(CharSequence cs) 将此字符串与指定的 CharSequence 比较。 |
boolean |
contentEquals(StringBuffer sb) 将此字符串与指定的 StringBuffer 比较。 |
static String |
copyValueOf(char[] data) 返回指定数组中表示该字符序列的 String。 |
static String |
copyValueOf(char[] data, int offset, int count) 返回指定数组中表示该字符序列的 String。 |
boolean |
endsWith(String suffix) 测试此字符串是否以指定的后缀结束。 |
boolean |
equals(Object anObject) 将此字符串与指定的对象比较。 |
boolean |
equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写。 |
static String |
format(Locale l, String format, Object... args) 使用指定的语言环境、格式字符串和参数返回一个格式化字符串。 |
static String |
format(String format, Object... args) 使用指定的格式字符串和参数返回一个格式化字符串。 |
byte[] |
getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
byte[] |
getBytes(Charset charset) 使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。 |
void |
getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) 已过时。 该方法无法将字符正确转换为字节。从 JDK 1.1 起,完成该转换的首选方法是通过 getBytes() 方法,该方法使用平台的默认字符集。 |
byte[] |
getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
void |
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此字符串复制到目标字符数组。 |
int |
hashCode() 返回此字符串的哈希码。 |
int |
indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。 |
int |
indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。 |
int |
indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。 |
int |
indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 |
String |
intern() 返回字符串对象的规范化表示形式。 |
boolean |
isEmpty() 当且仅当 length() 为 0 时返回 true。 |
int |
lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。 |
int |
lastIndexOf(int ch, int fromIndex) 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。 |
int |
lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引。 |
int |
lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 |
int |
length() 返回此字符串的长度。 |
boolean |
matches(String regex) 告知此字符串是否匹配给定的正则表达式。 |
int |
offsetByCodePoints(int index, int codePointOffset) 返回此 String 中从给定的 index 处偏移 codePointOffset 个代码点的索引。 |
boolean |
regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 测试两个字符串区域是否相等。 |
boolean |
regionMatches(int toffset, String other, int ooffset, int len) 测试两个字符串区域是否相等。 |
String |
replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 |
String |
replace(CharSequence target, CharSequence replacement) 使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 |
String |
replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
String |
replaceFirst(String regex, String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 |
String[] |
split(String regex) 根据给定正则表达式的匹配拆分此字符串。 |
String[] |
split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。 |
boolean |
startsWith(String prefix) 测试此字符串是否以指定的前缀开始。 |
boolean |
startsWith(String prefix, int toffset) 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。 |
CharSequence |
subSequence(int beginIndex, int endIndex) 返回一个新的字符序列,它是此序列的一个子序列。 |
String |
substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。 |
String |
substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个子字符串。 |
char[] |
toCharArray() 将此字符串转换为一个新的字符数组。 |
String |
toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 |
String |
toLowerCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。 |
String |
toString() 返回此对象本身(它已经是一个字符串!)。 |
String |
toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 |
String |
toUpperCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。 |
String |
trim() 返回字符串的副本,忽略前导空白和尾部空白。 |
static String |
valueOf(boolean b) 返回 boolean 参数的字符串表示形式。 |
static String |
valueOf(char c) 返回 char 参数的字符串表示形式。 |
static String |
valueOf(char[] data) 返回 char 数组参数的字符串表示形式。 |
static String |
valueOf(char[] data, int offset, int count) 返回 char 数组参数的特定子数组的字符串表示形式。 |
static String |
valueOf(double d) 返回 double 参数的字符串表示形式。 |
static String |
valueOf(float f) 返回 float 参数的字符串表示形式。 |
static String |
valueOf(int i) 返回 int 参数的字符串表示形式。 |
static String |
valueOf(long l) 返回 long 参数的字符串表示形式。 |
static String |
valueOf(Object obj) 返回 Object 参数的字符串表示形式。 |
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
以下开始正文:
首先从String类的开始, 依据以点带面的原则,
从String 类的结构开始,
public final class String extends Object
implements Serializable, Comparable<String>, CharSequence。
一、 看修饰符 public:可以被所有类访问(使用)。 (这个就不说了, 没事说的,唯一的说的就是,public 修饰符修饰的类,此类的文件名要和类名保持一致)
final : 使用此修饰符的类不能够被继承。
对于修饰符,我们着重看下,这个final的意义。
首先,final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。使用final来修饰的类叫作final类。final类通常功能是完整的,它们不能被继承。
其次,final关键字提高了性能。JVM和Java应用都会缓存final变量;final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销;使用final关键字,JVM会对方法、变量及类进行优化;创建不可变类要使用final关键字。不可变类是指它的对象一旦被创建了就不能被更改了。不可变类有很多好处,譬如它们的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销等等。
总结一下就是,每个创建出的String类的对象都会被JVM和java应用进行缓存(怎么个缓存机制先把这个话题搁置),而且JVM会对其优化(怎么优化先把这个话题搁置),而去不需要额外的同步开销保证线程安全。
1、对于String的finial 不可改变的对象,用一段代码说明一下,例子1。
String s = "a";
s = s+"b";
System.out.print(s);// result : ab
对于上述的这段代码,JVM是这样解析这段代码的:首先创建对象s,赋值为a,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,如果频繁的执行此类的操作,是内存开销比较大。
2、对于String的finial 不可改变的对象的应用,用一段代码说明一下,例子2。
public class test9 {
public static void main(String[] args) {
String str = "a";
StringBuilder stb = new StringBuilder("a");
String strAdd = addString(str);
StringBuilder stbApp = appStringBuilder(stb);
System.out.println("String before >>> "+str.toString());
System.out.println("String after >>> "+strAdd.toString());
System.out.println("StringBuilder before >>> "+stb.toString());
System.out.println("String after >>> "+stbApp.toString());
/*result:
String before >>> a
String after >>> ab
StringBuilder before >>> ab
String after >>> ab*/
}
private static String addString(String str) {
return str+="b";
}
private static StringBuilder appStringBuilder(StringBuilder stb) {
return stb.append("b");
}
因为java对象参数传的是引用,所以可变的StringBuffer参数就被改变了。而对于String对象由于finial修饰,具有不可变性。也就因为String的不可变性,只可以读不能写,保证了String对象的线程之间的共享安全安全。
未完待续。。
转载于:https://my.oschina.net/u/3707187/blog/1550703
相关推荐
这个压缩包 "selenium-java-2.47.1.zip" 包含了Selenium的Java版本,具体是2.47.1的更新,发布于2015年8月。这个版本在当时是一个稳定且广泛使用的版本,它提供了丰富的API,支持多种浏览器,并且可以与各种测试框架...
基于java的开发源码-Spring4GWT.zip 基于java的开发源码-Spring4GWT.zip 基于java的开发源码-Spring4GWT.zip 基于java的开发源码-Spring4GWT.zip 基于java的开发源码-Spring4GWT.zip 基于java的开发源码-Spring4GWT....
但如果仅从“开源”字面意义(开放可阅读的源码)上看,其实Sun自JDK 1.5之后就开始以Java Research License(JRL)的形式公布过Java源码,主要用于研究人员阅读(JRL许可证的开放源码至JDK 1.6 Update 23为止)。...
基于java的开发源码-EPUB类库 Epublib.zip 基于java的开发源码-EPUB类库 Epublib.zip 基于java的开发源码-EPUB类库 Epublib.zip 基于java的开发源码-EPUB类库 Epublib.zip 基于java的开发源码-EPUB类库 Epublib.zip ...
基于java的开发源码-OpenID服务器 JOIDS.zip 基于java的开发源码-OpenID服务器 JOIDS.zip 基于java的开发源码-OpenID服务器 JOIDS.zip 基于java的开发源码-OpenID服务器 JOIDS.zip 基于java的开发源码-OpenID服务器 ...
基于Java题库管理系统源码-毕设项目.zip基于Java题库管理系统源码-毕设项目.zip基于Java题库管理系统源码-毕设项目.zip基于Java题库管理系统源码-毕设项目.zip基于Java题库管理系统源码-毕设项目.zip基于Java题库...
基于java的开发源码-Decompiler反编译器.zip 基于java的开发源码-Decompiler反编译器.zip 基于java的开发源码-Decompiler反编译器.zip 基于java的开发源码-Decompiler反编译器.zip 基于java的开发源码-Decompiler反...
基于java的开发源码-Ajax框架 ZK.zip 基于java的开发源码-Ajax框架 ZK.zip 基于java的开发源码-Ajax框架 ZK.zip 基于java的开发源码-Ajax框架 ZK.zip 基于java的开发源码-Ajax框架 ZK.zip 基于java的开发源码-Ajax...
基于java的开发源码-EasyCms框架.zip 基于java的开发源码-EasyCms框架.zip 基于java的开发源码-EasyCms框架.zip 基于java的开发源码-EasyCms框架.zip 基于java的开发源码-EasyCms框架.zip 基于java的开发源码-...
基于java的开发源码-进程通信.zip 基于java的开发源码-进程通信.zip 基于java的开发源码-进程通信.zip 基于java的开发源码-进程通信.zip 基于java的开发源码-进程通信.zip 基于java的开发源码-进程通信.zip 基于java...
基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于...
《Java操作INI文件:org.dtools.javaini-v1.1.00源码解析》 在Java编程中,有时我们需要处理配置文件,其中INI文件是一种常见的格式,它以键值对的形式存储数据,通常用于存储软件的设置或配置信息。`org.dtools....
基于java的开发源码-餐饮门户.zip 基于java的开发源码-餐饮门户.zip 基于java的开发源码-餐饮门户.zip 基于java的开发源码-餐饮门户.zip 基于java的开发源码-餐饮门户.zip 基于java的开发源码-餐饮门户.zip 基于java...
基于java的开发源码-附加数据库.zip 基于java的开发源码-附加数据库.zip 基于java的开发源码-附加数据库.zip 基于java的开发源码-附加数据库.zip 基于java的开发源码-附加数据库.zip 基于java的开发源码-附加数据库....
Java项目源码-继承Monster.java
基于Java开发的BS结构驾校培训管理系统源码-高分毕设.zip基于Java开发的BS结构驾校培训管理系统源码-高分毕设.zip基于Java开发的BS结构驾校培训管理系统源码-高分毕设.zip基于Java开发的BS结构驾校培训管理系统源码-...
基于java的开发源码-Java项目源码在线相册系统.zip 基于java的开发源码-Java项目源码在线相册系统.zip 基于java的开发源码-Java项目源码在线相册系统.zip 基于java的开发源码-Java项目源码在线相册系统.zip 基于java...
java-uuid-generator-3.1.3.jar 部分开源源代码用到这里面的类。
基于java的开发源码-Java博客系统yijavaBlog.zip 基于java的开发源码-Java博客系统yijavaBlog.zip 基于java的开发源码-Java博客系统yijavaBlog.zip 基于java的开发源码-Java博客系统yijavaBlog.zip 基于java的开发...
基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java ...