构造函数体内定义的局部 class 有问题吗
Is there something wrong with the local class defined withn a constructor body
我有以下枚举:
enum FilterFactory {
INSTANCE;
private final Map<FilterType, Creator> creators;
private FilterFactory() {
creators = new HashMap<>();
class SimplCreator implements FilterCreator{
@Override
public FilterDTO createDto() {
return new FilterDTO();
}
} //Local class within the constructor
creators.put(FilterType.DATE, new FilterCreator(){
@Override
public FilterDTO createDto() {
return new DynamicDTO();
}
});
creators.put(FilterType.DROP_DOWN_LIST, new SimplCreator());
creators.put(FilterType.FIELD, new SimplCreator());
}
private static interface Creator{
public FilterDTO createDto();
}
//Other staff
}
问题是我从未在构造函数体内使用过本地 类。它会导致一些错误吗,这样做不好吗?还有,构造器enu的构造器。
我看到的唯一问题是,您正在为每个 FilterFactory 实例创建一个新的 FilterCreator 实例(这需要更多内存)。您可以通过创建一些常量来防止这种情况发生:
enum FilterFactory {
INSTANCE;
private final Map<FilterType, Creator> creators = new HashMap<>();
private static final SimplCreator DEFAULT_CREATOR = new Creator() {
@Override
public FilterDTO createDto() {
return new FilterDTO();
}
}
private static final FilterCreator DYNAMIC_CREATOR = new Creator(){
@Override
public FilterDTO createDto() {
return new DynamicDTO();
}
}
private FilterFactory() {
creators.put(FilterType.DATE, DYNAMIC_CREATOR);
creators.put(FilterType.DROP_DOWN_LIST, DEFAULT_CREATOR);
creators.put(FilterType.FIELD, DEFAULT_CREATOR);
}
private static interface Creator{
FilterDTO createDto();
}
//Other stuff
}
您的方法很好,但在 Java 8 中,您可以使用方法引用或 lambda 使其更好一些(并用更标准的 Supplier<FilterDTO>
替换您的 Creator):
import java.util.function.Supplier;
enum FilterFactory {
INSTANCE;
private final Map<FilterType, Supplier<FilterDTO>> creators;
private FilterFactory() {
creators = new EnumMap<>(FilterType.class); // a bit more efficient :)
creators.put(FilterType.DATE, DynamicDTO::new);
creators.put(FilterType.DROP_DOWN_LIST, SimpleDTO::new);
creators.put(FilterType.FIELD, SimpleDTO::new);
}
// other stuff ...
}
这里我使用构造函数的 method reference 来实例化 Supplier<FilterDTO>
。我也可以使用 lambda 表达式 "given nothing, give me a FilterDTO":
creators.put(FilterType.DATE, () -> new DynamicDTO());
...
这两个变体(方法参考与 lamdbas)基本上是等价的,你应该使用你更清楚的那个(引用:Java's language architect himself)。我个人觉得方法参考在视觉上更清晰,尽管它确实需要一点时间来适应。
我有以下枚举:
enum FilterFactory {
INSTANCE;
private final Map<FilterType, Creator> creators;
private FilterFactory() {
creators = new HashMap<>();
class SimplCreator implements FilterCreator{
@Override
public FilterDTO createDto() {
return new FilterDTO();
}
} //Local class within the constructor
creators.put(FilterType.DATE, new FilterCreator(){
@Override
public FilterDTO createDto() {
return new DynamicDTO();
}
});
creators.put(FilterType.DROP_DOWN_LIST, new SimplCreator());
creators.put(FilterType.FIELD, new SimplCreator());
}
private static interface Creator{
public FilterDTO createDto();
}
//Other staff
}
问题是我从未在构造函数体内使用过本地 类。它会导致一些错误吗,这样做不好吗?还有,构造器enu的构造器。
我看到的唯一问题是,您正在为每个 FilterFactory 实例创建一个新的 FilterCreator 实例(这需要更多内存)。您可以通过创建一些常量来防止这种情况发生:
enum FilterFactory {
INSTANCE;
private final Map<FilterType, Creator> creators = new HashMap<>();
private static final SimplCreator DEFAULT_CREATOR = new Creator() {
@Override
public FilterDTO createDto() {
return new FilterDTO();
}
}
private static final FilterCreator DYNAMIC_CREATOR = new Creator(){
@Override
public FilterDTO createDto() {
return new DynamicDTO();
}
}
private FilterFactory() {
creators.put(FilterType.DATE, DYNAMIC_CREATOR);
creators.put(FilterType.DROP_DOWN_LIST, DEFAULT_CREATOR);
creators.put(FilterType.FIELD, DEFAULT_CREATOR);
}
private static interface Creator{
FilterDTO createDto();
}
//Other stuff
}
您的方法很好,但在 Java 8 中,您可以使用方法引用或 lambda 使其更好一些(并用更标准的 Supplier<FilterDTO>
替换您的 Creator):
import java.util.function.Supplier;
enum FilterFactory {
INSTANCE;
private final Map<FilterType, Supplier<FilterDTO>> creators;
private FilterFactory() {
creators = new EnumMap<>(FilterType.class); // a bit more efficient :)
creators.put(FilterType.DATE, DynamicDTO::new);
creators.put(FilterType.DROP_DOWN_LIST, SimpleDTO::new);
creators.put(FilterType.FIELD, SimpleDTO::new);
}
// other stuff ...
}
这里我使用构造函数的 method reference 来实例化 Supplier<FilterDTO>
。我也可以使用 lambda 表达式 "given nothing, give me a FilterDTO":
creators.put(FilterType.DATE, () -> new DynamicDTO());
...
这两个变体(方法参考与 lamdbas)基本上是等价的,你应该使用你更清楚的那个(引用:Java's language architect himself)。我个人觉得方法参考在视觉上更清晰,尽管它确实需要一点时间来适应。