java中String学习
来源:互联网 发布:韩国聊天软件talk 编辑:程序博客网 时间:2024/05/26 12:06
1. String的不可变性
一旦一个String对象在内存中创建, 它将不可改变, 所有String类中方法并不是改变String对象自己, 而是重新创建一个新的String对象 .
第一行在常量池中创建一个”abc”对象,
第二行进行截取, 其实是重新创建一个对象, 然后让a重新指向这个截取对象 .
但是原来”abc”对象并没有变化 , 只是没有引用指向它, 最后被垃圾回收 .
也就是”abc”, 一旦创建就不会被修改 . 这就是不可变性 .
查看String源码 :
它的成员变量都是final, 尤其是value成员, 被final修饰, 表示这个变量一旦通过构造函数生成就不能被改变 .
所以String的不可变性并不是因为类被声明final(类被声明final只能代表可不可被继承), 真正决定不可变性, 是成员变量都被声明为final .
2. 代码
*常量 : final String a = "abc", 被final修饰, 那么a就是常量.
public static void main(String[] args) { /** * 1.常量池 * JVM存在一个常量池,其中保存很多String对象,并且可以被共享,提高效率 * 由于String类中成员是final, 它的值一旦创建不能被修改 * 字符串池由String类维护, 可以调用intern方法访问字符串池 . */ // 字符串池创建一个对象 String s1 = "abc"; // 字符串池中存在"abc",所以这次不需要创建对象 String s2 = "abc"; // 所以两个地址指向一致 . System.out.println("s1 == s2:"+(s1 == s2)); // true /** * 2.new String("") */ // 创建两个对象, 一个存在字符串池中, 一个存在堆中 String s3 = new String("abc"); // 池中已经存在"abc"对象, 所以只在堆中创建 String s4 = new String("abc"); // 所以s3和s4不相等,都在堆中,指向的内存区域不同 System.out.println("s3 == s4:"+(s3 == s4)); // false // 一个在pool中另一个在堆中 System.out.println("s1 == s3:"+(s1 == s3)); // false /** * 3.常量的值在编译时已经确定(优化) * 这里"ab"和"cd"都是常量, 因此"+"之后值在编译时确定 * 等同于 str = "abcd" */ String s5 = "ab" + "cd"; String s6 = "abcd"; System.out.println("s5 == s6:"+(s5 == s6)); // true /** * 4.局部变量s7,s8存储两个拘留字符串对象的地址 . * 那么下面(s7+s8)原理 : * 运行期JVM首先会在堆中创建一个StringBuilder对象, * 然后利用s7指向的拘留字符串完成初始化 * 然后调用append方法完成对s8指向的字符串进行合并 * 然后调用toString方法在堆中创建一个String对象 * 最后将刚生成的String对象地址存放在s9中. * s10存储的是字符串池中"abcd"对应的地址. * s9存储是堆中"abcd"对应地址 */ String s7 = "ab"; String s8 = "cd"; String s9 = s7 + s8; String s10 = "abcd"; System.out.println("s9 == s10:"+(s9 == s10)); // false /** * 5.java编译器对String+基本类型/常量, 当成常量表达式直接求值优化 * 运行期两个string相加,会产生新的对象, 存在堆中 */ String s11 = "b"; String s12 = "a" + s11; String s13 = "ab"; //因为s11是变量(被final修饰是常量),所以运行期才会被解析 System.out.println("s12 == s13:"+(s12 == s13) ); // false final String s14 = "b"; String s15 = "a" + s14; String s16 = "ab"; System.out.println("s15 == s16:"+(s15 == s16)); // true }
面试题:
曾经一个面试题 :
public static void main(String[] args) { String a = "hello"; String b = "hel" + "lo"; String c = "hel" + new String("lo"); final String d = "lo"; String e = "lo"; String f = "hel" + d; String g = "hel" + e; System.out.println(a == b); // true b是常量相加 System.out.println(a == c); // false new String会重新新建对象 System.out.println(a == f); // true d是常量(被final修饰) System.out.println(a == g); // false e是变量不会编译期优化 }
3.以前疑惑
对于String a = “abc”, 我总在思考 a 到底是字符串常量还是变量 . 你说它是常量, 他却没有被final修饰, 如果说变量但是”abc”会被放在常量池中 .
最后别人一句话点醒了我, a 是变量, “abc”是常量 . 我以前老纠结在 a 上, 导致概念各种混乱 .
如果a要变成常量 , 需要被final修饰 , final String a = “abc” .
0 0
- java中String学习
- 关于Java中String内存的学习
- Java中关于String学习总结
- java中String类源代码学习
- Java中有关String的学习笔记
- Java中String类的学习
- java 基础学习-03 api 中String类的学习
- [摘抄-学习中] Java中String 的妙用
- 【JAVA学习】JAVA中int、String的类型转换
- [Java学习]Java中String的内存机制/String的比较
- JAVA学习(二)__JAVA中int、String的类型转换
- Java中String,StringBuilder和StringBuffer类学习
- Java中String类以及相关的类的学习
- JAVA学习20_Java中String与byte[]的转换
- C++中string学习
- 学习java String类
- JAVA String类学习
- java.lang.String 学习
- push rejected of solution
- Poj 2823 Sliding Window(单调队列)
- Android xmlns
- android studio 报错resources-debug-stripped.ap_' specified for property 'resourceFile' does not exist.
- 191. Number of 1 Bits
- java中String学习
- 非沪籍未来何去何从?4月23日上海软考说明会-职称评审-居转户加分140分
- Less学习笔记
- 移动测试中游戏和应用的不同之处
- 用训练好的caffemodel做前向
- java基础知识四
- express的基本配置项
- windows下查看动态库和静态库的函数接口
- 搜索