https://blog.csdn.net/qq_45950109/article/details/116992408?utm_medium=distribute.pc_category.none-task-blog-hot-7.nonecase&depth_1-utm_source=distribute.pc_category.none-task-blog-hot-7.nonecase
基本特性
String s1 = “hello” //字面量的定义方式,会存放在堆内存的字符串常量池
String s2 = new String(“hello”) //对象方式,存对象实例化放在堆内存
final修饰
实现Serializable接口(支持序列化)
实现Comparable接口(可以比较大小)
String在jdk1.8前定义final char[] value 存储String数据
jdk1.9改为byte[],以减小空间
String Pool底层Hashtable
String Pool底层Hashtable,固定长度1009.
数据过多会导致hash冲突,冲突严重时会让本应该添加到常量池的字符串添加到哈希表元素对应的链表中,
链表过长则String.intern性能下降
使用-XX:StringTableSize=长度 可设置StringTable的长度
JDK6中String Table是固定的1009
jdk7后String Table默认长度60013,最小1009
String内分配
String常量池
8种基本类型的常量池就类似一个Java系统级别提供的缓存
new创建的String通过intern()存储到常量池
jdk6前字符串常量池存放在永久代
jdk7后存放在堆(和普通对象一样,若调优则对堆分配内存)
jdk8元空间替代永久代
String Table调整原因
永久代默认空间小,JVM频率低,容易OOM
String字符串拼接
两个字符串相加相当于直接把这两个字符串合在一起,而不是两个字符串重新进行拼接
字符串拼接底层原理
new StringBuilder() new String()
append()
toString()
jdk5之后用StringBuffer
String字符串拼接操作与StringBuilder的append方法追加字符串操作的效率对比
动态代理两种方式
https://www.cnblogs.com/myitnews/p/12940371.html
动态代理的方式有两种:
- JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
- CGLIB动态代理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
JDK动态代理和CGLIB字节码生成的区别?
- JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
- CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。