可怜一个无法自证的字符串常量池存储的到底是对象还是引用的问题,百度只有我一个人理解了他?
1547 2020-12-22 14:27
首先,栈存储了基础数据类型和对象引用,这是一个线程内,一个方法调用栈帧的基础效率。
栈指向了堆的实例,得到了对象的内容,这是面向对象动态加载的精髓。脱离了编译链接的过程式语言的束缚。
方法区是一个规范,如何实现它取决于各大公司以及版本。这是一个设计思想。落实下去。有了1.6版本和1.7以上关于运行时常量池内(尤其是涉及到字符串常量池)而不是类文件常量池的一些区别。这个问题无法自证的原因也在于只能比对引用地址的hashcode而无法获取到真实的运行时的内存id。但是这之间的区别却被人反复拿来说事:说1.6以前存储的是对象。1.7以后存储的是引用。
就在这时,一个“程序员dmz”的家伙给美团jvm团队去了一封石沉大海杳无音信的留言。说1.6也是存储的引用。因为常量池就是一个hashset。一口咬定里面不可能存对象。他说的没错。并且他也画出了在永久代存着常量池引用指向的对象来说明问题。这个细分的说法。得不到大神的认可。也无从佐证。囫囵吞枣的说。有人能区分永久代和方法区。有人能区分常量池和方法区。有人能依据官方文档自jdk1.8将字符串常量池移到了堆中。但是更多的人则拍死了1.6之前常量池存的就是对象内容。包括面试题都说是创建了两个对象。没错。你们说的都没错。但是细微之处见真章。没有几个人理解了程序员dmz所说的就在常量池边上。永久代(或者说方法区)上面创建常量池实例本尊的那个对象。常量池存的实际上就是靠他这一边的对象的引用。
综上所述。你们认为这个对象就是在常量池中,也可以理解。但是让你们理解这个很严谨的设计思想的实现实际上更深一步,有着很细微的差别。这就是另一层境界了。可能这个门槛就拦下了好多人。因为没人能证明它。只有设计着知道。而语言的分层不就是为了让底层技术面向上层透明么。所以,理解不了的,就真的没有本事去理解了。
全部评论