『壹』 java常量池是什么有什么用 和堆、栈有关系求简单易懂的解释!
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间
这里我们主要关心栈,堆和常量池,对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
『贰』 项目中的常量是放在接口里还是放在类里呢
《Java与模式》 ,里面提了一句不建议使用常量接口,甚至举了个java源码的反例。
1、常量类应该是final,不变的,而接口里的参数是final,也是不变的。
那么,看起来接口是放常量没有一定问题,还省去了final的输入,非常的合适。
但是,类是只能单继承的,接口是允许多实现的。
要是类实现的多个接口出现重名的常量,会报错,必须要在实现类明确常量用的是哪个接口的。
虽然这可以说是架构师设计的问题,但是,架构师这么做就违反了依赖倒转原则,这玩意就不细说了。
2、如果某个实现了常量接口的类被修改不再需要常量了,也会因为序列化兼容原因不得不保持该实现,而且非final类实现常量接口会导致所有子类被污染。
这个应该很少人遇到过,不过这是 Effective Java 里面说的。
具体的理解就是,能被序列化的一定是数据,
那么突然改了数据结构,可能导致老版的数据无法被反序列化,而新版的数据会有冗杂的数据,
要是折腾个几次,网络传输协议 这个无法通过时间或者空间提升的玩意就能逼死你了。
3、基于数据只暴露给相应的类的原则,一个类实现一个常量接口,可能只需要其中几个常量,而得到了更多无用的常量,
所以,使用常量接口的时候都是
1.接口是定义类型的,而不应该用于导出常量。常量接口不建议使用,应使用常量类。
2.访问:接口. 常量 , 因为在接口定义 常量 默认是 static 的。
大佬的分析: http://www.360doc.com/content/14/1210/17/16650130_431828218.shtml