避免Java中的重复字符串
我想问一个关于在Java中避免字符串重复的问题
上下文是一个带有如下标记和属性的XML:
<product id="PROD" name="My Product"...></product>
使用JibX,这种XML在如下类中进行编组/解编组:
public class Product{
private String id;
private String name;
// constructor, getters, setters, methods and so on
}
该程序是一个长时间的批处理过程,因此需要创建、使用、复制产品对象等
嗯,问题是: 当我用Eclipse memory analyzer(MAT)这样的软件分析执行时,我发现了几个重复的字符串。例如,在id属性中,PROD值在2000个实例左右重复,以此类推
我怎样才能避免这种情况?Product类中的其他属性可能会在执行过程中更改其值,但属性如id,name。。。不要经常改变
我读了一些关于字符串的东西。intern()方法,但我还没有使用,我不确定这是否是一个解决方案。我能在类中定义像静态final常量这样的属性中最常见的值吗
我希望我用正确的方式表达了我的问题。 非常感谢您的帮助或建议。提前谢谢
# 1 楼答案
另一种解决方案:
您可以尝试在
@id
属性上定义<xs:enumeration/>
限制(如果您的域模型允许这样做的话)。如果JibX与JAXB或其他XML Java映射标准一样智能,那么可以将其映射为具有常量文本的Javaenum
,可以大量重用对于
ID
值,我会尝试这样做,因为它在我看来有点像一个枚举# 2 楼答案
虽然^{} 可以通过将每个值减少到一个唯一的
String
实例来解决这个问题,但它会引入另一个问题:每个intern()
-edString
都可以在JVM中存活很长时间。如果ID变化很大(即它们不是有限集合的一部分,但可以是任何值),那么从长远来看,这可能会产生巨大的负面影响Edit:我曾经声称
intern()
-ed字符串永远不能被GCed,但是@nanda证明了我对this JavaWorld article的错误。虽然这在一定程度上减少了intern()
带来的问题,但它仍然没有完全移除:intern()
提供的池无法控制,可能会在垃圾收集方面产生意外的结果)幸运的是Guava以^{} 接口和它的助手类^{} 的形式提供了一个解决方案:使用^{} 可以创建一个对象,它可以像
String.intern()
一样充当唯一String
对象的“池”,除了池绑定到该实例,如果放弃该池,然后,内容也可以进行垃圾收集# 3 楼答案
众所周知,字符串对象可以通过两种方式创建,一种是使用文本,另一种是通过new运算符
如果使用像
String test = "Sample";
这样的文本,那么它将被缓存在字符串对象池中。因此,这里不需要实习,因为默认情况下字符串对象将被缓存但是如果你创建一个字符串对象,比如string test=new string(“Sample”);那么这个字符串对象将不会被添加到字符串池中。因此,这里我们需要使用
String test = new String("Sample").intern();
将字符串对象强制推送到字符串缓存因此,建议使用字符串文字而不是新运算符
所以在您的例子中,private static final String id=“PROD”;这是正确的解决方案