static final String =" something" - 静电有意义吗?

时间:2014-10-03 09:51:43

标签: java string immutability object-pooling

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),但我认为这些不是合并的......为什么?

谢谢, 卡罗

5 个答案:

答案 0 :(得分:3)

开发人员使用此模式的原因有几个,即使您对运行时行为的分析及其对字符串池的使用是正确的。

  1. 它更清晰地传达开发人员的意图。具体来说,字符串现在的名称希望比常量更清晰,并且它传达的运行时行为并非每个人都知道(或者他们不时忘记)。
  2. 如果开发人员想要更改源文件中的值,并且已经在多个地方使用过,那么只有一个地方可以进行更改。
  3. 一旦决定使用变量,关键字static将意味着内存使用率更低。也就是说,只有一个字段用于存储ref,而不是每个对象实例的一个字段。
  4. 关于你的后续问题:

    1. 问:为什么显式调用String构造函数不会导致String被合并?上面的代码使用新的String(“hello”)print false。
    2. 因为字符串池仅用于字符串文字,所以如JLS所述并且调用构造函数不会被归类为字符串文字。

      1. 问:是否为字符串保留了池化行为?
      2. 字符串池仅用于字符串文字,但当然还有其他用于不同用例的缓存。跳到脑海中最明显的一个是用于优化自动装箱的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