要了解如何修复它,您应该首先了解它在做什么。为此,您需要了解两件事:
- Anonymous sub-classes
- Instance initializer blocks
如何修复它的 TL;DR 只是将那些 put 调用和初始化从 setter 中分离出来:
Map<String, String> valueMap = new LinkedHashMap<String, String>();
valueMap.put("0", "None");
valueMap.put("1", "Subtle");
valueMap.put("2", "Intrusive");
notifyTypeItem.setValueMap(valueMap);
继续阅读以了解正在发生的事情以及为什么它可能是一种不好的方法。
匿名子类
匿名类通常只是一个没有名字的类。例如,您可以创建像Runnable 这样的接口的匿名实例:
Runnable r = new Runnable() {
@Override
public void run() {
// Do something
}
};
r.run(); // Does that something
同样,您也可以创建抽象类和具体类的匿名实例。例如,创建ThreadLocal 的匿名实例是很常见的:
private static ThreadLocal<SimpleDateFormat> localIsoDateFormat = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
}
当您不需要完整的专用类来覆盖一两个方法时,这很有用,类似于只使用一种方法创建接口的匿名实例。
实例初始化块
实例初始化程序块允许您在构造函数之外执行初始化程序。例如:
public class MyClass {
private final String s;
{
s = "My Class String";
}
public String getS() { return s; }
}
它本质上是构造函数的替代品,通常没有必要,所以你很少看到它。它几乎总是可以移动到构造函数中。
组合它们
您的示例结合了它们。它正在创建LinkedHashMap 的匿名子类,然后它还使用了一个初始化块。格式更正确,您的代码是:
Map<String, String> map = new LinkedHashMap<>() {
{
put("0", "None");
put("1", "Subtle");
put("2", "Intrusive");
}
};
它是LinkedHashMap 的匿名实例,带有一个执行put 调用的实例初始化程序块。
为什么不好?
出于同样的原因,您需要 be careful creating anonymous classes: 对封闭类实例的引用。
匿名类因成为应用程序内存泄漏的根源而臭名昭著。您的代码似乎在非static 上下文中。这意味着您创建的匿名LinkedHashMap 子类将隐式引用您的方法所在的类。例如,如果您的方法位于MyClass:
public class MyClass {
private SelectItem notifyTypeItem = new SelectItem();
public void foo() {
notifyTypeItem.setTitle("Default Notification");
notifyTypeItem.setWidth("100%");
notifyTypeItem.setValueMap(new LinkedHashMap<String, String>() {{
put("0", "None");
put("1", "Subtle");
put("2", "Intrusive");
}}
);
}
}
新创建的LinkedHashMap 子类(MyClass$1 将是“类名”,如果你可以这样称呼它)将引用封闭的MyClass 实例。在某些情况下,这可能没问题。但是,如果您创建notifyTypeItem 的目的是将其传递给其他东西并丢弃您的MyClass 实例,那么您将在应用程序中创建内存泄漏。 MyClass 实例将被MyClass$1 实例引用,SelectItem 将引用MyClass$1 实例,因此在SelectItem 实例不再被引用之前,MyClass 实例永远不会被垃圾回收。如果MyClass 除了SelectItem 之外还有其他几个引用,那么这只会增加单个MyClass 实例消耗的总内存,并导致更多的内存泄漏问题。
参考文献
以下是一些相关链接: