首先明白一件事:【变量存放在栈中,对象存放在堆中】
一、享元设计模式【应用于包装数据类型,属于引用数据类型】
当包装数据类加载到JVM中时,会在堆中创建一个独特的区域(下文称为享元池)。
然后当你声明了一个变量且想要让这个变量成为一个包装类对象的引用时,
JDK提供有两种方式(①new语句和②静态赋值语句),
变量很好理解,不需要解释,
可对象是指什么呢?
对象就是操作者在代码语句中具体声明的事物:
①在new语句中的话是括号内的值
PS:这时候应该注意一点,在new语句中
String类的话,对象可以是空(就是括号内啥都不填,哈希值为0)
但是在包装类中对象不能为空,否则报错
②在静态赋值语句中的话就是等号后的值
)
而若是静态赋值,包装类优先从享元池中寻找对象
若是找到,那么直接将这个对象的地址返回变量;
找不到就在享元池外创建对象,然后再将这个对象的地址返回变量。
若是new语句赋值,包装类跳过享元池,
直接在享元池外创建对象,然后将这个对象的地址返回变量。
String常量池:
其实String常量池也用到了享元设计模式的思想,
特殊的是:String常量池是可以扩容的
前提条件一样是当你声明了一个变量且想要让这个变量成为一个String类对象的引用时,
1)若是静态赋值,String类优先从常量池中寻找对象
若是找到,那么直接将这个对象的地址返回变量;
没找到就在常量池创建对象,然后再将这个对象的地址返回变量。
----->所以String类的静态赋值的对象地址永远在常量池中
2)若是new语句赋值,String类扫描常量池,
若是找到,那么直接在常量池外创建对象,然后再将这个对象的地址返回变量。
没找到就需要常量池中创建对象,然后再在常量池外创建对象,然后再将这个对象的地址返回变量
------->意思就是String类一旦创建了从没有出现过的对象,必定优先创建一个存放在常量池中,new语句没机会调用,但是可以供静态赋值语句使用