我最近在我正在处理的现有代码库中运行了以下代码段,并添加了您在那里看到的评论。我知道这段特殊的代码可以重写为更清晰,但我只是想知道我的分析是否正确。
java会创建一个新的类声明并将其存储在perm gen空间中,以便每次调用此方法,还是会知道重用现有的声明?
protected List<Object> extractParams(HibernateObjectColumn column, String stringVal) {
// FIXME: could be creating a *lot* of anonymous classes which wastes perm-gen space right?
return new ArrayList<Object>() {
{
add("");
}
};
}
答案 0 :(得分:15)
该类只编译一次(在编译时)。编译器提取一个类(名为MyOuterClass$1
)并使用它。当然,它会创建多个实例,但它们都属于同一个类。您可以看到,当您编译.java
文件并查看生成的.class
文件时,将会有一个用于内部匿名类。
答案 1 :(得分:5)
不,这会创建一个单个类的许多实例。要测试,请将其放在匿名类中:
@Override
public String toString() {
return getClass().getName();
}
然后在匿名类的各种实例上调用toString()
。你会看到他们都返回相同的班级名称。
答案 2 :(得分:3)
其他答案都是正确的。
然而:
如果您的代码中多次重复该模式,那么将以相同数量的内部类结束。如果您使用该模式数百次/数千次,则增加的代码占用空间/ permgen使用量可能非常重要。
您在此特定示例中所做的工作可以更简单地表达为
protected List<Object> extractParams(HibernateObjectColumn column,
String stringVal) {
return Collections.singletonList("");
}
对于必须使用多个值填充列表的情况,涉及静态辅助方法的解决方案可能更简单。
答案 3 :(得分:0)
声明许多相同的匿名类会浪费java中的内存吗?
当然可以,但您在发布的代码中没有这样做。