构造函数体内定义的局部 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)。我个人觉得方法参考在视觉上更清晰,尽管它确实需要一点时间来适应。