Java源码学习
1、一些基本概念
堆:jvm运行中申请的对象存放的位置。也就是所说的新生代+老年代,YGC就发生在这 里虚拟机栈:每个方法在被调用执行时都会创建一个虚拟机栈,用于存储临时的遍历、方法等信息。调用相当于进栈,返回结果则相当于出栈,异常输出的栈信息就是从这里来的。本地方法栈:也是方法调用,只是调用的方法是本地native方法方法区:存储的类的结构信息,静态变量等信息。也就是永生代,发生FULL GC的地方(Java8中以元空间代替了永生代这个概念)常量池:方法区的一部分,用来存放各种生成的字面量,例如定义的一个String类型的数据(Java7中把常量池移到了堆中)2、创建字符串
String s1="hello"; String s2=new String("hello"); 12
第一种方法是在栈中创建一个String类型的引用s1,然后在常量池中寻找,如果常量池中存在hello的字符串数据,则直接把s1指向常量池中hello的地址;否则会在常量池中创建hello这个字符串数据,然后把s1指向新创建的hello地址。
第二种方法是在栈中创建一个String类型的引用s2,然后在常量池中寻找,如果常量池中存在该数据,则在堆中复制拷贝该数据,然后把s2指向堆中新建的地址;否则会创建一个字符串存放在常量池中,然后进行拷贝一份到堆中,s2指向堆的地址。
通过new创建的string一定会在堆中创建一份数据,同时常量池肯定有一个值的备份操作;而单独的字符串则是直接指向常量池,所以一般还是使用字符串更好些,具体可看如下的图解
3、字符串 + 操作
String s1="helloworld" String s2="hello" + "world" String s3=new String("hello") + "world" System.out.println(s1 == s2); // true System.out.println(s2 == s3); // false System.out.println(s1 == s3); // false 1234567
代码中"hello" + "world"在编译期已经知道了数据情况(使用javac编译查看class文件会发现s1和s2是一致的),JVM会自动优化使得s1和s2是一样的,s3由于有new操作,所以需要StringBuilder的append完成,具体可看如下图解。
4、字符串变量 + 操作
String s1="hello" String s2="world" String s3="helloworld" String s4=s1 + s2 System.out.println(s3 == s4); // false 123456
这里的样例和上一个样例存在一些差别,这里的s4是由s1 + s2获得的,在编译期无法感知到其实际值,在运行期时会利用StringBuilder的append剩下一个新的String对象,所以s3指向的是常量池,而s4指向的堆,两者自然是不一样的。
s4 = new StringBuilder()).append(s1).append(s2).toString()
5、带final的字符串变量 + 操作
final String s1="hello" String s2="world" String s3="helloworld" String s4=s1 + "world" String s5=s1 + s2 System.out.println(s3 == s4); // true System.out.println(s3 == s5); // false 12345678
添加了final关键字修饰的变量在编译期会被对应的字符串直接替换掉,相当于字符串数据,而包含了字符串变量的+操作则依旧是使用了StringBuilder
6、反射修改字符串
常规上,字符串都是不可变的(imutable),所以线程安全。但是,可以通过反射手段修改字符串!!!因为底层是char[],获取到之后可以强行修改。
@Test public void test5() throws NoSuchFieldException, IllegalAccessException { String s = "hello"; System.out.println("修改前 s = " + s); //value是String内部字段:private final char value[]; Field value = s.getClass().getDeclaredField("value"); value.setAccessible(true); char[] s1 = (char[])value.get(s); s1[0] = 'A'; System.out.println("修改后 s = " + s); } 123456789101112
总结
String 本身是final类型的类,在日常使用中需要频繁的做字符串合并操作时,尽可能的使用StringBuilder(如需要考虑线程安全则使用StringBuffer),降低无谓的字符串创建操作,在保证安全的情况下,提高效率!
相关知识
宠物店管理系统源码解析与Java实现
Java计算机毕业设计宠物用品商城系统(开题报告+源码+论文)
Java精品项目源码第40期宠物医院在线预约挂号系统
java宠物商城源码
计算机毕业设计Java宠物领养系统(源码+系统+mysql数据库+lw文档)
如何学习Java?一份完整的Java学习路线指南
Java基于用户画像和数据挖掘的学习行为研究(开题+源码)
[独有源码]java
Java基于Java宠物寄存管理系统(开题+源码)
Java实战项目
网址: Java源码学习 https://www.mcbbbk.com/newsview611809.html
上一篇: 如何饲养金钱龟?食物选择与水量控 |
下一篇: 乌龟百科︱龟宝宝是如何诞生的? |
推荐分享

- 1我的狗老公李淑敏33——如何 5096
- 2南京宠物粮食薄荷饼宠物食品包 4363
- 3家养水獭多少钱一只正常 3825
- 4豆柴犬为什么不建议养?可爱的 3668
- 5自制狗狗辅食:棉花面纱犬的美 3615
- 6狗交配为什么会锁住?从狗狗生 3601
- 7广州哪里卖宠物猫狗的选择性多 3535
- 8湖南隆飞尔动物药业有限公司宠 3477
- 9黄金蟒的价格 3396
- 10益和 MATCHWELL 狗 3352