深入探索 Java-String
来源:互联网 发布:大数据与信息安全报告 编辑:程序博客网 时间:2024/05/21 19:29
1. 字符串常量池(Literal Pool)
Java使用一个字符串常量池来统一保存字符串的字面值,这样可以复用,节省内存。
字符串字字面值是一个由双引号括起来的字符序列。它是指向一个String实例的引用。
比如 String s = “abc”。对于“abc”,它首先是一个String literal,它在创建之后,立即利用String的intern方法,装入到了字符串常量池并返回这个String 实例的引用给s。当你再次写abc”的时候,intern方法会先查看是否已有这个literal了,就会直接返回这个literal对应的String实例的引用。也就是说你循环1000变,内存里面也只有这么一个String literal以及他对应的String的实例。
2. 编译时计算和运行时计算的区别
String s1 = "abc";
String s2 = "abc";
String s3 = s1 + s2; // 运行时确定s3的值
String s4 = "abc" + "abc"; // 编译时在常量池会生成字符串字面值“abcabc”
String s5 = "ab" + "cabc"; // 编译时直接复用常量池中的字符串字面值“abcabc”
System.out.println(s3 == s4); // 返回false
System.out.println(s4 == s5); // 返回true
3. hashCode值
Java对象统一存储在哈希表中,使用对象时会根据hashCode值去获取对象,如果两个不同对象的hashcode相同,会在哈希表中发生冲突,
哈希表中会通过链表来存储这两个不同对象。
Java对象的hashCode值是根据Java对象的内存地址计算出相应的方法,函数hashCode是父类Object的方法,
调用的是native方法。
a、如果两个对象相同(及a==b),那么它们的hashCode值一定要相同;
b、如果两个对象的hashCode相同,它们并不一定相同;
4. String的equals()方法
String类的equals()方法,覆写了Object类的equals()方法,判断当前字符串与传进来的字符串的内容是否一致。
所以字符串相等的判断是用equals()方法,而不是使用==。
String中的equals()方法源代码如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
Object对象quals()方法源代码
public boolean equals(Object o) {
return this == o;//比较两个对象是否相等
}
5. String 类为什么是final
a. 字符串常量池(String pool, String intern pool, String保留池) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。
如下面的代码所示,将会在堆内存中只创建一个实际String对象.
String s1 = "abcd";
String s2 = "abcd”;
字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码.
c. 安全性
String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。
参考文档
http://www.programcreek.com/2013/04/why-string-is-immutable-in-java/
Java使用一个字符串常量池来统一保存字符串的字面值,这样可以复用,节省内存。
字符串字字面值是一个由双引号括起来的字符序列。它是指向一个String实例的引用。
比如 String s = “abc”。对于“abc”,它首先是一个String literal,它在创建之后,立即利用String的intern方法,装入到了字符串常量池并返回这个String 实例的引用给s。当你再次写abc”的时候,intern方法会先查看是否已有这个literal了,就会直接返回这个literal对应的String实例的引用。也就是说你循环1000变,内存里面也只有这么一个String literal以及他对应的String的实例。
2. 编译时计算和运行时计算的区别
String s1 = "abc";
String s2 = "abc";
String s3 = s1 + s2; // 运行时确定s3的值
String s4 = "abc" + "abc"; // 编译时在常量池会生成字符串字面值“abcabc”
String s5 = "ab" + "cabc"; // 编译时直接复用常量池中的字符串字面值“abcabc”
System.out.println(s3 == s4); // 返回false
System.out.println(s4 == s5); // 返回true
3. hashCode值
Java对象统一存储在哈希表中,使用对象时会根据hashCode值去获取对象,如果两个不同对象的hashcode相同,会在哈希表中发生冲突,
哈希表中会通过链表来存储这两个不同对象。
Java对象的hashCode值是根据Java对象的内存地址计算出相应的方法,函数hashCode是父类Object的方法,
调用的是native方法。
a、如果两个对象相同(及a==b),那么它们的hashCode值一定要相同;
b、如果两个对象的hashCode相同,它们并不一定相同;
4. String的equals()方法
String类的equals()方法,覆写了Object类的equals()方法,判断当前字符串与传进来的字符串的内容是否一致。
所以字符串相等的判断是用equals()方法,而不是使用==。
String中的equals()方法源代码如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
Object对象quals()方法源代码
public boolean equals(Object o) {
return this == o;//比较两个对象是否相等
}
5. String 类为什么是final
a. 字符串常量池(String pool, String intern pool, String保留池) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。
如下面的代码所示,将会在堆内存中只创建一个实际String对象.
String s1 = "abcd";
String s2 = "abcd”;
假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象. 严格来说,这种常量池的思想,是一种优化手段.
b. 允许String对象缓存HashCode
Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码.
c. 安全性
String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。
参考文档
http://www.programcreek.com/2013/04/why-string-is-immutable-in-java/
0 0
- 深入探索 Java-String
- 深入探索Java-数据类型
- 深入探索Java-Hashmap
- 深入探索Java-ArrayList
- 深入探索-JAVA线程
- Java String探索
- 深入探索Java工作原理
- 深入探索-JAVA内存管理
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 深入探索java热部署
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 深入探索 Java 热部署
- 推荐几个国内Ubuntu更新源
- 黑马程序员_javaIO流笔记
- Insertion Sort List
- hdu 2462(数论:欧拉定理+快速幂取模优化+欧拉函数)
- 关于Hibernate不能自动生成数据库表-POJO和映射文件正确但是访问对应表出错-的原因
- 深入探索 Java-String
- linux安装glassfish
- 用Ajax实现二级联动
- 自恋,有什么好处?
- poj 2923 Relocation(状态压缩+01背包)
- 题目1512:用两个栈实现队列
- uC/OS II内存管理 详细分析
- 阿里面试题-单件模式及相关问题
- offset()和position()的区别