在Java中,在一个循环中多次实例化一个对象是一种不好的做法吗?
我正在处理一个Java项目,一个变量在while循环中反复实例化为局部变量
while ((inputLine = in.readLine()) != null){
Matcher matcher = pattern.matcher(inputLine);
isFound = matcher.find();
if(isFound){
break;
}
}
问题是,局部变量匹配器每次都在while循环中实例化,直到循环终止
我在想,这会不会减慢处理时间
# 1 楼答案
一般来说,没有。通常情况下,你需要这样做。当然,您确实希望避免虚假和过多的堆栈分配,因为它们不是免费的,但是在许多非常好的情况下,您需要在循环中创建一个对象
实例化和声明之间也有区别。在您的示例中,
pattern.matcher(inputLine)
是您的对象实例化;你只是用这句话创建了一个新的匹配器Matcher matcher = ...
是您的声明。如果您询问是否可以在循环中多次声明变量,这同样取决于上下文。通常,这很好,事实上比在循环外部声明变量更可取,因为匹配器的每个实例的范围(大概)都应该限制在循环的单个迭代中。这个作用域机制可以帮助您避免以后在应用程序中产生bug# 2 楼答案
视情况而定
在这种特殊情况下,可以这样做。这是因为
inputLine
在循环的每次迭代中都在变化。如果不在每次迭代中创建一个新的Matcher
,您就无法做到这一点。另外,Matcher
的构造函数似乎就是这样做的:我不会说那是很多
在其他可以避免创建实例的情况下,应避免创建实例。循环中的字符串串联就是一个很好的例子
例如:
您应该使用
StringBuilder
# 3 楼答案
视情况而定。对于这个特殊的案例,其他人已经回答了你的问题。一般来说,在循环中实例化一个对象,以便在年轻一代的集合中对其进行清理,通常(但并非总是)效果更好。Java的GC针对短期对象进行了优化
变量的范围需要符合情况的逻辑,而不是关于“更好”的教条。对象可能比变量更长寿,例如在循环中:
这里,
candidate
变量在循环之后超出范围。如果指定了一个非null
值,则result
变量将指向超出其原始引用的对象。所有其他候选人都有资格获得GC。(这个例子是精心设计的,但旨在说明这一点。)例外情况是当初始化开销很大,并且在循环内不重复时。如果对象的构造是巨大的,并且循环只改变对象状态的一些小部分而不重复大量的工作,那么您可以考虑在循环之外创建对象。p>
“大规模”有多大?很难知道。但对象创建几乎是免费的,年轻一代GC也几乎是免费的。死对象不会增加年轻的GC开销。当对象处于长期状态时,GC开销会增加,所以您希望保持生命周期尽可能短
生命周期管理是Java编程的黑暗艺术之一。不过,如果你喜欢尽快扔掉东西,你基本上不会出错。要偏离这一经验法则,您必须衡量不同生命周期策略之间的差异。在某些情况下,将对象保留更长的时间可以显著提高性能,但如果您对其进行研究,您会发现结果是通过大量实验和精确的度量来实现的
# 4 楼答案
在我看来,您使用Matcher对象的方式应该在循环外部实例化,然后使用它
# 5 楼答案
在Java here中进行模式匹配的标准模式是: