短生命对象中的长静态字符串

时间:2013-04-17 08:44:25

标签: java

这可能是一个愚蠢的问题(或者只是让我看起来很愚蠢:)),但是我会对如何在短期对象的上下文中使用长String对象感兴趣。

考虑在cron作业或匿名,命令或类似函数的类中进行长SQL查询。这些是非常短命的类,甚至在大多数时间里都会使用这些长字符串一次。什么是更好的?要构造一个String inline并让它与实例一起收集,或者将它设为静态final,并让它们在内存中无用,直到下一个实例化的类?

4 个答案:

答案 0 :(得分:8)

嗯,你可以对String发生的事情进行过多的控制。

即使你内联创建它,该String很可能会被添加到JVM的String常量池中,并且当你再次声明它时会被重用,所以在实践中,你可能会重用相同的String对象无论哪种方式。

除非字符串太大以至于它对应用程序的性能产生影响,否则我不会担心它并选择对我来说更具可读性的选项。

如果该String仅在代码的一个特定点使用,在方法内部,我会将其声明为内联,我更喜欢将我的变量放在尽可能最小的范围内,但这里的意见可能会有所不同。 如果没有任何变化,并且在您的特定用例中似乎有意义,那么无论如何都要将String声明为静态,我怀疑它会影响性能。

答案 1 :(得分:2)

字符串常量进入类的常量池,无法进行优化,即处理得足够好。

创建长字符串一个静态不做。对于SQL,使用带有?占位符的预备语句。对于带有占位符的字符串也是如此:使用 MessageFormat

要明确。以下内容不需要额外费用:

static final String s = "... long string ...";

答案 2 :(得分:-2)

当剩余内存有限时,JVM通常会执行perm gen space清理和卸载未使用/未引用的类。因此,将长字符串作为静态变量在我看来不会造成太大伤害

答案 3 :(得分:-2)

如果您觉得您的Strings可以占用大量内存,那么不要将它们设置为静态或使用String literal声明它们。因为这两个都将存储在permgen空间中并且几乎完全被垃圾收集[有机会但是很小,静态可能永远不会被垃圾收集,因为你还没有创建自己的类加载器]。 因此,使用new运算符创建String,以便在堆中创建,并且可以很容易地进行垃圾收集,即

String str = new String("long string");

编辑:

如何存储字符串:http://www.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html

编辑:

下面对新String的工作原理进行了长时间的讨论。提出的参数是新的String将在堆中创建2个对象,在池中创建一个对象。这是错误的,默认情况下不是这样,您可以通过调用intern方法强制java执行此操作。为了支持我的论证,下面是来自Strin类的javadoc for intern方法:

  

实习生

     

public String intern()返回。的规范表示   字符串对象。保持最初为空的字符串池   私有地通过String类。

     

当调用实习方法时,如果池已包含   字符串等于此字符串对象由equals(Object)确定   方法,然后返回池中的字符串。否则,这个   String对象被添加到池中以及对此String的引用   返回对象。

     

对于任何两个字符串s和t,s.intern()== t.intern()   当且仅当s.equals(t)为真时才为真。

     

所有文字字符串和字符串值常量表达式都是   实习。字符串文字在Java语言的§3.10.5中定义   说明书

从上面的文档可以看出,如果新的String总是在池中创建一个对象,那么实习方法将完全没用!!从逻辑上讲,它没有任何意义。

编辑:

同时阅读这篇文章的答案:String pool creating two string objects for same String in Java