static final String = "something";
我想知道这样的声明在Java中是否具有某种真正的感。我已经在代码中找到了数千个时间,但是学习和使用字符串我已经学会了,无论你声明一个String
对象多少次都没关系:如果你之前的某个类声明了这个字符串,那么它就是汇集的reused(我说的是没有显式构造函数调用而创建的String)
public class StringCompare {
private void toCompare(String h) {
String x = "hello";
System.out.println( x == h);
}
public void compare() {
String h = "hello";
toCompare(h);
}
}
实际上,这段代码在调用compare时打印true
,因此2个变量引用同一个对象。说final
变量无法重新定义,static
字在这种情况下完全无用。我错过了这一点吗?
更多事情:
1 - 为什么显式调用String
构造函数不会导致String被合并?使用new String("hello")
打印false
,上面的代码相同。
2 - 是否为字符串保留了池化行为?还有一些其他不可变对象(比如BigInteger),但我认为这些不是合并的......为什么?
谢谢, 卡罗
答案 0 :(得分:3)
开发人员使用此模式的原因有几个,即使您对运行时行为的分析及其对字符串池的使用是正确的。
关于你的后续问题:
因为字符串池仅用于字符串文字,所以如JLS所述并且调用构造函数不会被归类为字符串文字。
字符串池仅用于字符串文字,但当然还有其他用于不同用例的缓存。跳到脑海中最明显的一个是用于优化自动装箱的int缓存。
答案 1 :(得分:2)
即使静态不会在这种情况下为您带来内存优势,您仍然可以以静态方式访问该字段,因此您不需要实例。例如,您经常使用一些URI,因此您创建以下类:
public class Uris
{
public static final String GOOGLE = "http://google.com";
public static final String BBC = "http://bbc.co.uk";
}
使用静态,您只需使用Uris.GOOGLE
代替新的Uris().GOOGLE
。
答案 2 :(得分:1)
static
意味着对于为该类创建的每个新对象,String构造&汇集只需要发生一次,永远。这是一个小的计算节省。
答案 3 :(得分:1)
这是因为String ="hello"
或String h
没有在堆中创建任何对象,这些对象都存储在String constant pool
中,其中new String("hello");
在堆中创建一个新对象,因此地址会有所不同
查看详细信息here
答案 4 :(得分:0)
String x = "hello";
String h = "hello";
是两个String
文字。它们位于公共池中(String池的一部分)。有同样的参考。然后==
检查您将获得的引用true
如果您使用String x = new String("hello")
,则会创建一个新的String
对象x
。当然是指新的参考。现在比较参考给你false
。